[automerger skipped] Merge "Bump Fragment and Navigation to rc01" into androidx-main am: 218ccafb21 -s ours

am skip reason: Merged-In I16c46049d1404b1252313979bb2788fe9edbc02a with SHA-1 8de119ce39 is already in history

Original change: https://android-review.googlesource.com/c/platform/frameworks/support/+/2069614

Change-Id: I7c95af855d4a5a0c2a6eef50a4efb6d402862aad
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/activity/activity-compose/build.gradle b/activity/activity-compose/build.gradle
index 8ef2c0b..0738c22 100644
--- a/activity/activity-compose/build.gradle
+++ b/activity/activity-compose/build.gradle
@@ -37,7 +37,7 @@
     // Outside of androidx this is resolved via constraint added to lifecycle-common,
     // but it doesn't work in androidx.
     // See aosp/1804059
-    implementation("androidx.lifecycle:lifecycle-common-java8:2.5.0-rc01")
+    implementation("androidx.lifecycle:lifecycle-common-java8:2.5.0-beta01")
 
     androidTestImplementation projectOrArtifact(":compose:ui:ui-test-junit4")
     androidTestImplementation projectOrArtifact(":compose:material:material")
diff --git a/activity/activity-ktx/api/1.5.0-beta01.txt b/activity/activity-ktx/api/1.5.0-beta01.txt
index 822d245..0a94311 100644
--- a/activity/activity-ktx/api/1.5.0-beta01.txt
+++ b/activity/activity-ktx/api/1.5.0-beta01.txt
@@ -18,7 +18,7 @@
 package androidx.activity.contextaware {
 
   public final class ContextAwareKt {
-    method public static suspend inline <R> Object? withContextAvailable(androidx.activity.contextaware.ContextAware, kotlin.jvm.functions.Function1<? super android.content.Context,? extends R> onContextAvailable, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withContextAvailable(androidx.activity.contextaware.ContextAware, kotlin.jvm.functions.Function1<? super android.content.Context,? extends R> onContextAvailable, kotlin.coroutines.Continuation<? super R> p);
   }
 
 }
diff --git a/activity/activity-ktx/api/public_plus_experimental_1.5.0-beta01.txt b/activity/activity-ktx/api/public_plus_experimental_1.5.0-beta01.txt
index f690f03..0ca1317 100644
--- a/activity/activity-ktx/api/public_plus_experimental_1.5.0-beta01.txt
+++ b/activity/activity-ktx/api/public_plus_experimental_1.5.0-beta01.txt
@@ -11,7 +11,7 @@
   }
 
   public final class PipHintTrackerKt {
-    method @RequiresApi(android.os.Build.VERSION_CODES.O) @kotlinx.coroutines.ExperimentalCoroutinesApi public static suspend Object? trackPipAnimationHintView(android.app.Activity, android.view.View view, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) @kotlinx.coroutines.ExperimentalCoroutinesApi public static suspend Object? trackPipAnimationHintView(android.app.Activity, android.view.View view, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
   }
 
 }
@@ -19,7 +19,7 @@
 package androidx.activity.contextaware {
 
   public final class ContextAwareKt {
-    method public static suspend inline <R> Object? withContextAvailable(androidx.activity.contextaware.ContextAware, kotlin.jvm.functions.Function1<? super android.content.Context,? extends R> onContextAvailable, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withContextAvailable(androidx.activity.contextaware.ContextAware, kotlin.jvm.functions.Function1<? super android.content.Context,? extends R> onContextAvailable, kotlin.coroutines.Continuation<? super R> p);
   }
 
 }
diff --git a/activity/activity-ktx/api/restricted_1.5.0-beta01.txt b/activity/activity-ktx/api/restricted_1.5.0-beta01.txt
index 822d245..0a94311 100644
--- a/activity/activity-ktx/api/restricted_1.5.0-beta01.txt
+++ b/activity/activity-ktx/api/restricted_1.5.0-beta01.txt
@@ -18,7 +18,7 @@
 package androidx.activity.contextaware {
 
   public final class ContextAwareKt {
-    method public static suspend inline <R> Object? withContextAvailable(androidx.activity.contextaware.ContextAware, kotlin.jvm.functions.Function1<? super android.content.Context,? extends R> onContextAvailable, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withContextAvailable(androidx.activity.contextaware.ContextAware, kotlin.jvm.functions.Function1<? super android.content.Context,? extends R> onContextAvailable, kotlin.coroutines.Continuation<? super R> p);
   }
 
 }
diff --git a/activity/activity-ktx/build.gradle b/activity/activity-ktx/build.gradle
index 21e4e1a..6b5ab06 100644
--- a/activity/activity-ktx/build.gradle
+++ b/activity/activity-ktx/build.gradle
@@ -28,11 +28,11 @@
     api("androidx.core:core-ktx:1.1.0") {
         because "Mirror activity dependency graph for -ktx artifacts"
     }
-    api("androidx.lifecycle:lifecycle-runtime-ktx:2.5.0-rc01") {
+    api("androidx.lifecycle:lifecycle-runtime-ktx:2.5.0-beta01") {
         because 'Mirror activity dependency graph for -ktx artifacts'
     }
-    api("androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0-rc01")
-    api("androidx.savedstate:savedstate-ktx:1.2.0-rc01") {
+    api("androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0-beta01")
+    api("androidx.savedstate:savedstate-ktx:1.2.0-beta01") {
         because 'Mirror activity dependency graph for -ktx artifacts'
     }
     api(libs.kotlinStdlib)
diff --git a/activity/activity/api/current.txt b/activity/activity/api/current.txt
index e01b95c..9edb424 100644
--- a/activity/activity/api/current.txt
+++ b/activity/activity/api/current.txt
@@ -65,6 +65,7 @@
     method @MainThread public void addCallback(androidx.lifecycle.LifecycleOwner, androidx.activity.OnBackPressedCallback);
     method @MainThread public boolean hasEnabledCallbacks();
     method @MainThread public void onBackPressed();
+    method @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public void setOnBackInvokedDispatcher(android.window.OnBackInvokedDispatcher);
   }
 
   public interface OnBackPressedDispatcherOwner extends androidx.lifecycle.LifecycleOwner {
@@ -163,6 +164,21 @@
     method public androidx.activity.result.IntentSenderRequest.Builder setFlags(int, int);
   }
 
+  public final class PickVisualMediaRequest {
+    method public androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType getMediaType();
+    property public final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType mediaType;
+  }
+
+  public static final class PickVisualMediaRequest.Builder {
+    ctor public PickVisualMediaRequest.Builder();
+    method public androidx.activity.result.PickVisualMediaRequest build();
+    method public androidx.activity.result.PickVisualMediaRequest.Builder setMediaType(androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType mediaType);
+  }
+
+  public final class PickVisualMediaRequestKt {
+    method public static androidx.activity.result.PickVisualMediaRequest PickVisualMediaRequest(optional androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType mediaType);
+  }
+
 }
 
 package androidx.activity.result.contract {
@@ -239,6 +255,47 @@
     method public android.net.Uri? parseResult(int resultCode, android.content.Intent? intent);
   }
 
+  @RequiresApi(19) public static class ActivityResultContracts.PickMultipleVisualMedia extends androidx.activity.result.contract.ActivityResultContract<androidx.activity.result.PickVisualMediaRequest,java.util.List<android.net.Uri>> {
+    ctor public ActivityResultContracts.PickMultipleVisualMedia(optional int maxItems);
+    method @CallSuper public android.content.Intent createIntent(android.content.Context context, androidx.activity.result.PickVisualMediaRequest input);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.util.List<android.net.Uri>>? getSynchronousResult(android.content.Context context, androidx.activity.result.PickVisualMediaRequest input);
+    method public final java.util.List<android.net.Uri> parseResult(int resultCode, android.content.Intent? intent);
+  }
+
+  public static class ActivityResultContracts.PickVisualMedia extends androidx.activity.result.contract.ActivityResultContract<androidx.activity.result.PickVisualMediaRequest,android.net.Uri> {
+    ctor public ActivityResultContracts.PickVisualMedia();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context context, androidx.activity.result.PickVisualMediaRequest input);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri>? getSynchronousResult(android.content.Context context, androidx.activity.result.PickVisualMediaRequest input);
+    method public static final boolean isPhotoPickerAvailable();
+    method public final android.net.Uri? parseResult(int resultCode, android.content.Intent? intent);
+    field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion Companion;
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.Companion {
+    method public boolean isPhotoPickerAvailable();
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.ImageAndVideo implements androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType {
+    field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.ImageAndVideo INSTANCE;
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.ImageOnly implements androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType {
+    field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.ImageOnly INSTANCE;
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.SingleMimeType implements androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType {
+    ctor public ActivityResultContracts.PickVisualMedia.SingleMimeType(String mimeType);
+    method public String getMimeType();
+    property public final String mimeType;
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.VideoOnly implements androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType {
+    field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VideoOnly INSTANCE;
+  }
+
+  public static sealed interface ActivityResultContracts.PickVisualMedia.VisualMediaType {
+  }
+
   public static final class ActivityResultContracts.RequestMultiplePermissions extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.Map<java.lang.String,java.lang.Boolean>> {
     ctor public ActivityResultContracts.RequestMultiplePermissions();
     method public android.content.Intent createIntent(android.content.Context context, String![] input);
diff --git a/activity/activity/api/public_plus_experimental_current.txt b/activity/activity/api/public_plus_experimental_current.txt
index e01b95c..9edb424 100644
--- a/activity/activity/api/public_plus_experimental_current.txt
+++ b/activity/activity/api/public_plus_experimental_current.txt
@@ -65,6 +65,7 @@
     method @MainThread public void addCallback(androidx.lifecycle.LifecycleOwner, androidx.activity.OnBackPressedCallback);
     method @MainThread public boolean hasEnabledCallbacks();
     method @MainThread public void onBackPressed();
+    method @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public void setOnBackInvokedDispatcher(android.window.OnBackInvokedDispatcher);
   }
 
   public interface OnBackPressedDispatcherOwner extends androidx.lifecycle.LifecycleOwner {
@@ -163,6 +164,21 @@
     method public androidx.activity.result.IntentSenderRequest.Builder setFlags(int, int);
   }
 
+  public final class PickVisualMediaRequest {
+    method public androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType getMediaType();
+    property public final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType mediaType;
+  }
+
+  public static final class PickVisualMediaRequest.Builder {
+    ctor public PickVisualMediaRequest.Builder();
+    method public androidx.activity.result.PickVisualMediaRequest build();
+    method public androidx.activity.result.PickVisualMediaRequest.Builder setMediaType(androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType mediaType);
+  }
+
+  public final class PickVisualMediaRequestKt {
+    method public static androidx.activity.result.PickVisualMediaRequest PickVisualMediaRequest(optional androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType mediaType);
+  }
+
 }
 
 package androidx.activity.result.contract {
@@ -239,6 +255,47 @@
     method public android.net.Uri? parseResult(int resultCode, android.content.Intent? intent);
   }
 
+  @RequiresApi(19) public static class ActivityResultContracts.PickMultipleVisualMedia extends androidx.activity.result.contract.ActivityResultContract<androidx.activity.result.PickVisualMediaRequest,java.util.List<android.net.Uri>> {
+    ctor public ActivityResultContracts.PickMultipleVisualMedia(optional int maxItems);
+    method @CallSuper public android.content.Intent createIntent(android.content.Context context, androidx.activity.result.PickVisualMediaRequest input);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.util.List<android.net.Uri>>? getSynchronousResult(android.content.Context context, androidx.activity.result.PickVisualMediaRequest input);
+    method public final java.util.List<android.net.Uri> parseResult(int resultCode, android.content.Intent? intent);
+  }
+
+  public static class ActivityResultContracts.PickVisualMedia extends androidx.activity.result.contract.ActivityResultContract<androidx.activity.result.PickVisualMediaRequest,android.net.Uri> {
+    ctor public ActivityResultContracts.PickVisualMedia();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context context, androidx.activity.result.PickVisualMediaRequest input);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri>? getSynchronousResult(android.content.Context context, androidx.activity.result.PickVisualMediaRequest input);
+    method public static final boolean isPhotoPickerAvailable();
+    method public final android.net.Uri? parseResult(int resultCode, android.content.Intent? intent);
+    field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion Companion;
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.Companion {
+    method public boolean isPhotoPickerAvailable();
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.ImageAndVideo implements androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType {
+    field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.ImageAndVideo INSTANCE;
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.ImageOnly implements androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType {
+    field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.ImageOnly INSTANCE;
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.SingleMimeType implements androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType {
+    ctor public ActivityResultContracts.PickVisualMedia.SingleMimeType(String mimeType);
+    method public String getMimeType();
+    property public final String mimeType;
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.VideoOnly implements androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType {
+    field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VideoOnly INSTANCE;
+  }
+
+  public static sealed interface ActivityResultContracts.PickVisualMedia.VisualMediaType {
+  }
+
   public static final class ActivityResultContracts.RequestMultiplePermissions extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.Map<java.lang.String,java.lang.Boolean>> {
     ctor public ActivityResultContracts.RequestMultiplePermissions();
     method public android.content.Intent createIntent(android.content.Context context, String![] input);
diff --git a/activity/activity/api/restricted_current.txt b/activity/activity/api/restricted_current.txt
index 5fdb966..ae5d775 100644
--- a/activity/activity/api/restricted_current.txt
+++ b/activity/activity/api/restricted_current.txt
@@ -64,6 +64,7 @@
     method @MainThread public void addCallback(androidx.lifecycle.LifecycleOwner, androidx.activity.OnBackPressedCallback);
     method @MainThread public boolean hasEnabledCallbacks();
     method @MainThread public void onBackPressed();
+    method @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public void setOnBackInvokedDispatcher(android.window.OnBackInvokedDispatcher);
   }
 
   public interface OnBackPressedDispatcherOwner extends androidx.lifecycle.LifecycleOwner {
@@ -162,6 +163,21 @@
     method public androidx.activity.result.IntentSenderRequest.Builder setFlags(int, int);
   }
 
+  public final class PickVisualMediaRequest {
+    method public androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType getMediaType();
+    property public final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType mediaType;
+  }
+
+  public static final class PickVisualMediaRequest.Builder {
+    ctor public PickVisualMediaRequest.Builder();
+    method public androidx.activity.result.PickVisualMediaRequest build();
+    method public androidx.activity.result.PickVisualMediaRequest.Builder setMediaType(androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType mediaType);
+  }
+
+  public final class PickVisualMediaRequestKt {
+    method public static androidx.activity.result.PickVisualMediaRequest PickVisualMediaRequest(optional androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType mediaType);
+  }
+
 }
 
 package androidx.activity.result.contract {
@@ -238,6 +254,47 @@
     method public android.net.Uri? parseResult(int resultCode, android.content.Intent? intent);
   }
 
+  @RequiresApi(19) public static class ActivityResultContracts.PickMultipleVisualMedia extends androidx.activity.result.contract.ActivityResultContract<androidx.activity.result.PickVisualMediaRequest,java.util.List<android.net.Uri>> {
+    ctor public ActivityResultContracts.PickMultipleVisualMedia(optional int maxItems);
+    method @CallSuper public android.content.Intent createIntent(android.content.Context context, androidx.activity.result.PickVisualMediaRequest input);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<java.util.List<android.net.Uri>>? getSynchronousResult(android.content.Context context, androidx.activity.result.PickVisualMediaRequest input);
+    method public final java.util.List<android.net.Uri> parseResult(int resultCode, android.content.Intent? intent);
+  }
+
+  public static class ActivityResultContracts.PickVisualMedia extends androidx.activity.result.contract.ActivityResultContract<androidx.activity.result.PickVisualMediaRequest,android.net.Uri> {
+    ctor public ActivityResultContracts.PickVisualMedia();
+    method @CallSuper public android.content.Intent createIntent(android.content.Context context, androidx.activity.result.PickVisualMediaRequest input);
+    method public final androidx.activity.result.contract.ActivityResultContract.SynchronousResult<android.net.Uri>? getSynchronousResult(android.content.Context context, androidx.activity.result.PickVisualMediaRequest input);
+    method public static final boolean isPhotoPickerAvailable();
+    method public final android.net.Uri? parseResult(int resultCode, android.content.Intent? intent);
+    field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.Companion Companion;
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.Companion {
+    method public boolean isPhotoPickerAvailable();
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.ImageAndVideo implements androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType {
+    field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.ImageAndVideo INSTANCE;
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.ImageOnly implements androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType {
+    field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.ImageOnly INSTANCE;
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.SingleMimeType implements androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType {
+    ctor public ActivityResultContracts.PickVisualMedia.SingleMimeType(String mimeType);
+    method public String getMimeType();
+    property public final String mimeType;
+  }
+
+  public static final class ActivityResultContracts.PickVisualMedia.VideoOnly implements androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType {
+    field public static final androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VideoOnly INSTANCE;
+  }
+
+  public static sealed interface ActivityResultContracts.PickVisualMedia.VisualMediaType {
+  }
+
   public static final class ActivityResultContracts.RequestMultiplePermissions extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.Map<java.lang.String,java.lang.Boolean>> {
     ctor public ActivityResultContracts.RequestMultiplePermissions();
     method public android.content.Intent createIntent(android.content.Context context, String![] input);
diff --git a/activity/activity/build.gradle b/activity/activity/build.gradle
index 91a8e4d..6c6041d 100644
--- a/activity/activity/build.gradle
+++ b/activity/activity/build.gradle
@@ -17,11 +17,11 @@
 dependencies {
     api("androidx.annotation:annotation:1.1.0")
     implementation("androidx.collection:collection:1.0.0")
-    api("androidx.core:core:1.8.0-rc01")
-    api("androidx.lifecycle:lifecycle-runtime:2.5.0-rc01")
-    api("androidx.lifecycle:lifecycle-viewmodel:2.5.0-rc01")
-    api("androidx.savedstate:savedstate:1.2.0-rc01")
-    api("androidx.lifecycle:lifecycle-viewmodel-savedstate:2.5.0-rc01")
+    api(projectOrArtifact(":core:core"))
+    api("androidx.lifecycle:lifecycle-runtime:2.5.0-beta01")
+    api("androidx.lifecycle:lifecycle-viewmodel:2.5.0-beta01")
+    api("androidx.savedstate:savedstate:1.2.0-beta01")
+    api("androidx.lifecycle:lifecycle-viewmodel-savedstate:2.5.0-beta01")
     implementation("androidx.tracing:tracing:1.0.0")
     api(libs.kotlinStdlib)
 
diff --git a/activity/activity/src/androidTest/java/androidx/activity/ComponentActivityResultTest.kt b/activity/activity/src/androidTest/java/androidx/activity/ComponentActivityResultTest.kt
index 3e7fefd..389c8bc 100644
--- a/activity/activity/src/androidTest/java/androidx/activity/ComponentActivityResultTest.kt
+++ b/activity/activity/src/androidTest/java/androidx/activity/ComponentActivityResultTest.kt
@@ -115,6 +115,7 @@
             finish()
         }
     }
+    @Suppress("DEPRECATION")
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         launcher.launch(intent.getParcelableExtra("destinationIntent"))
diff --git a/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt b/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt
new file mode 100644
index 0000000..5e1790d
--- /dev/null
+++ b/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2022 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
+
+import android.os.Build
+import android.window.OnBackInvokedCallback
+import android.window.OnBackInvokedDispatcher
+import androidx.annotation.RequiresApi
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+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)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S_V2)
+class OnBackPressedDispatcherInvokerTest {
+
+    @Test
+    fun testSimpleInvoker() {
+        var registerCount = 0
+        var unregisterCount = 0
+        val invoker = object : OnBackInvokedDispatcher {
+            override fun registerOnBackInvokedCallback(p0: Int, p1: OnBackInvokedCallback) {
+                registerCount++
+            }
+
+            override fun unregisterOnBackInvokedCallback(p0: OnBackInvokedCallback) {
+                unregisterCount++
+            }
+        }
+
+        val dispatcher = OnBackPressedDispatcher()
+
+        dispatcher.setOnBackInvokedDispatcher(invoker)
+
+        val callback = object : OnBackPressedCallback(true) {
+            override fun handleOnBackPressed() { }
+        }
+
+        dispatcher.addCallback(callback)
+
+        assertThat(registerCount).isEqualTo(1)
+
+        callback.remove()
+
+        assertThat(unregisterCount).isEqualTo(1)
+    }
+
+    @Test
+    fun testInvokerEnableDisable() {
+        var registerCount = 0
+        var unregisterCount = 0
+        val invoker = object : OnBackInvokedDispatcher {
+            override fun registerOnBackInvokedCallback(p0: Int, p1: OnBackInvokedCallback) {
+                registerCount++
+            }
+
+            override fun unregisterOnBackInvokedCallback(p0: OnBackInvokedCallback) {
+                unregisterCount++
+            }
+        }
+
+        val dispatcher = OnBackPressedDispatcher()
+
+        dispatcher.setOnBackInvokedDispatcher(invoker)
+
+        val callback = object : OnBackPressedCallback(true) {
+            override fun handleOnBackPressed() { }
+        }
+
+        dispatcher.addCallback(callback)
+
+        assertThat(registerCount).isEqualTo(1)
+
+        callback.isEnabled = false
+
+        assertThat(unregisterCount).isEqualTo(1)
+
+        callback.isEnabled = true
+
+        assertThat(registerCount).isEqualTo(2)
+    }
+
+    @Test
+    fun testCallbackEnabledDisabled() {
+        val callback = object : OnBackPressedCallback(false) {
+            override fun handleOnBackPressed() {
+                TODO("Not yet implemented")
+            }
+        }
+
+        callback.isEnabled = true
+        callback.isEnabled = false
+    }
+
+    @Test
+    fun testInvokerAddDisabledCallback() {
+        var registerCount = 0
+        var unregisterCount = 0
+        val invoker = object : OnBackInvokedDispatcher {
+            override fun registerOnBackInvokedCallback(p0: Int, p1: OnBackInvokedCallback) {
+                registerCount++
+            }
+
+            override fun unregisterOnBackInvokedCallback(p0: OnBackInvokedCallback) {
+                unregisterCount++
+            }
+        }
+
+        val callback = object : OnBackPressedCallback(false) {
+            override fun handleOnBackPressed() { }
+        }
+
+        val dispatcher = OnBackPressedDispatcher()
+
+        dispatcher.setOnBackInvokedDispatcher(invoker)
+
+        dispatcher.addCallback(callback)
+
+        assertThat(registerCount).isEqualTo(0)
+
+        callback.isEnabled = true
+
+        assertThat(registerCount).isEqualTo(1)
+
+        callback.isEnabled = false
+
+        assertThat(unregisterCount).isEqualTo(1)
+    }
+
+    @Test
+    fun testInvokerAddEnabledCallbackBeforeSet() {
+        var registerCount = 0
+        var unregisterCount = 0
+        val invoker = object : OnBackInvokedDispatcher {
+            override fun registerOnBackInvokedCallback(p0: Int, p1: OnBackInvokedCallback) {
+                registerCount++
+            }
+
+            override fun unregisterOnBackInvokedCallback(p0: OnBackInvokedCallback) {
+                unregisterCount++
+            }
+        }
+
+        val callback = object : OnBackPressedCallback(true) {
+            override fun handleOnBackPressed() { }
+        }
+
+        val dispatcher = OnBackPressedDispatcher()
+        dispatcher.addCallback(callback)
+
+        dispatcher.setOnBackInvokedDispatcher(invoker)
+
+        assertThat(registerCount).isEqualTo(1)
+
+        callback.isEnabled = false
+
+        assertThat(unregisterCount).isEqualTo(1)
+    }
+}
diff --git a/activity/activity/src/main/java/androidx/activity/ComponentActivity.java b/activity/activity/src/main/java/androidx/activity/ComponentActivity.java
index 3f531b3..2410764 100644
--- a/activity/activity/src/main/java/androidx/activity/ComponentActivity.java
+++ b/activity/activity/src/main/java/androidx/activity/ComponentActivity.java
@@ -150,8 +150,8 @@
                 @Override
                 public void run() {
                     // Calling onBackPressed() on an Activity with its state saved can cause an
-                    // error on devices on API levels before 26. We catch that specific error and
-                    // throw all others.
+                    // error on devices on API levels before 26. We catch that specific error
+                    // and throw all others.
                     try {
                         ComponentActivity.super.onBackPressed();
                     } catch (IllegalStateException e) {
@@ -170,6 +170,7 @@
 
     private final ActivityResultRegistry mActivityResultRegistry = new ActivityResultRegistry() {
 
+        @SuppressWarnings("deprecation")
         @Override
         public <I, O> void onLaunch(
                 final int requestCode,
@@ -352,6 +353,9 @@
         mContextAwareHelper.dispatchOnContextAvailable(this);
         super.onCreate(savedInstanceState);
         ReportFragment.injectIfNeededIn(this);
+        if (Build.VERSION.SDK_INT >= 33) {
+            mOnBackPressedDispatcher.setOnBackInvokedDispatcher(getOnBackInvokedDispatcher());
+        }
         if (mContentLayoutId != 0) {
             setContentView(mContentLayoutId);
         }
diff --git a/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.java b/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.java
index 5fc26dc..ae3d314 100644
--- a/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.java
+++ b/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.java
@@ -18,6 +18,8 @@
 
 import androidx.annotation.MainThread;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.util.Consumer;
 import androidx.lifecycle.LifecycleOwner;
 
 import java.util.concurrent.CopyOnWriteArrayList;
@@ -44,6 +46,7 @@
 
     private boolean mEnabled;
     private CopyOnWriteArrayList<Cancellable> mCancellables = new CopyOnWriteArrayList<>();
+    private Consumer<Boolean> mEnabledConsumer;
 
     /**
      * Create a {@link OnBackPressedCallback}.
@@ -69,6 +72,9 @@
     @MainThread
     public final void setEnabled(boolean enabled) {
         mEnabled = enabled;
+        if (mEnabledConsumer != null) {
+            mEnabledConsumer.accept(mEnabled);
+        }
     }
 
     /**
@@ -106,4 +112,8 @@
     void removeCancellable(@NonNull Cancellable cancellable) {
         mCancellables.remove(cancellable);
     }
+
+    void setIsEnabledConsumer(@Nullable Consumer<Boolean> isEnabled) {
+        mEnabledConsumer = isEnabled;
+    }
 }
diff --git a/activity/activity/src/main/java/androidx/activity/OnBackPressedDispatcher.java b/activity/activity/src/main/java/androidx/activity/OnBackPressedDispatcher.java
index 6ff39f1..9e53b71 100644
--- a/activity/activity/src/main/java/androidx/activity/OnBackPressedDispatcher.java
+++ b/activity/activity/src/main/java/androidx/activity/OnBackPressedDispatcher.java
@@ -17,10 +17,16 @@
 package androidx.activity;
 
 import android.annotation.SuppressLint;
+import android.os.Build;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.MainThread;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.core.util.Consumer;
 import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LifecycleEventObserver;
 import androidx.lifecycle.LifecycleOwner;
@@ -59,6 +65,42 @@
     @SuppressWarnings("WeakerAccess") /* synthetic access */
     final ArrayDeque<OnBackPressedCallback> mOnBackPressedCallbacks = new ArrayDeque<>();
 
+    private Consumer<Boolean> mEnabledConsumer;
+
+    private OnBackInvokedCallback mOnBackInvokedCallback;
+    private OnBackInvokedDispatcher mInvokedDispatcher;
+    private boolean mBackInvokedCallbackRegistered = false;
+
+    /**
+     * Sets the {@link OnBackInvokedDispatcher} for handling system back for Android SDK T+.
+     *
+     * @param invoker the OnBackInvokedDispatcher to be set on this dispatcher
+     */
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    public void setOnBackInvokedDispatcher(@NonNull OnBackInvokedDispatcher invoker) {
+        mInvokedDispatcher = invoker;
+        updateBackInvokedCallbackState();
+    }
+
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    void updateBackInvokedCallbackState() {
+        boolean shouldBeRegistered = hasEnabledCallbacks();
+        if (mInvokedDispatcher != null) {
+            if (shouldBeRegistered && !mBackInvokedCallbackRegistered) {
+                Api33Impl.registerOnBackInvokedCallback(
+                        mInvokedDispatcher,
+                        OnBackInvokedDispatcher.PRIORITY_OVERLAY,
+                        mOnBackInvokedCallback
+                );
+                mBackInvokedCallbackRegistered = true;
+            } else if (!shouldBeRegistered && mBackInvokedCallbackRegistered) {
+                Api33Impl.unregisterOnBackInvokedCallback(mInvokedDispatcher,
+                        mOnBackInvokedCallback);
+                mBackInvokedCallbackRegistered = false;
+            }
+        }
+    }
+
     /**
      * Create a new OnBackPressedDispatcher that dispatches System back button pressed events
      * to one or more {@link OnBackPressedCallback} instances.
@@ -76,6 +118,19 @@
      */
     public OnBackPressedDispatcher(@Nullable Runnable fallbackOnBackPressed) {
         mFallbackOnBackPressed = fallbackOnBackPressed;
+        if (Build.VERSION.SDK_INT >= 33) {
+            mEnabledConsumer = aBoolean -> {
+                if (Build.VERSION.SDK_INT >= 33) {
+                    updateBackInvokedCallbackState();
+                }
+            };
+            mOnBackInvokedCallback = new OnBackInvokedCallback() {
+                @Override
+                public void onBackInvoked() {
+                    onBackPressed();
+                }
+            };
+        }
     }
 
     /**
@@ -114,6 +169,10 @@
         mOnBackPressedCallbacks.add(onBackPressedCallback);
         OnBackPressedCancellable cancellable = new OnBackPressedCancellable(onBackPressedCallback);
         onBackPressedCallback.addCancellable(cancellable);
+        if (Build.VERSION.SDK_INT >= 33) {
+            updateBackInvokedCallbackState();
+            onBackPressedCallback.setIsEnabledConsumer(mEnabledConsumer);
+        }
         return cancellable;
     }
 
@@ -152,6 +211,10 @@
 
         onBackPressedCallback.addCancellable(
                 new LifecycleOnBackPressedCancellable(lifecycle, onBackPressedCallback));
+        if (Build.VERSION.SDK_INT >= 33) {
+            updateBackInvokedCallbackState();
+            onBackPressedCallback.setIsEnabledConsumer(mEnabledConsumer);
+        }
     }
 
     /**
@@ -208,6 +271,10 @@
         public void cancel() {
             mOnBackPressedCallbacks.remove(mOnBackPressedCallback);
             mOnBackPressedCallback.removeCancellable(this);
+            if (Build.VERSION.SDK_INT >= 33) {
+                mOnBackPressedCallback.setIsEnabledConsumer(null);
+                updateBackInvokedCallbackState();
+            }
         }
     }
 
@@ -251,4 +318,25 @@
             }
         }
     }
+
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    static class Api33Impl {
+        private Api33Impl() { }
+
+        @DoNotInline
+        static void registerOnBackInvokedCallback(
+                OnBackInvokedDispatcher onBackInvokedDispatcher, int priority,
+                OnBackInvokedCallback onBackInvokedCallback
+        ) {
+            onBackInvokedDispatcher.registerOnBackInvokedCallback(priority, onBackInvokedCallback);
+        }
+
+        @DoNotInline
+        static void unregisterOnBackInvokedCallback(
+                OnBackInvokedDispatcher onBackInvokedDispatcher,
+                OnBackInvokedCallback onBackInvokedCallback
+        ) {
+            onBackInvokedDispatcher.unregisterOnBackInvokedCallback(onBackInvokedCallback);
+        }
+    }
 }
diff --git a/activity/activity/src/main/java/androidx/activity/result/PickVisualMediaRequest.kt b/activity/activity/src/main/java/androidx/activity/result/PickVisualMediaRequest.kt
new file mode 100644
index 0000000..f9b3bee
--- /dev/null
+++ b/activity/activity/src/main/java/androidx/activity/result/PickVisualMediaRequest.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2022 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.result
+
+import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType
+import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.ImageAndVideo
+
+/**
+ * Creates a request for a
+ * [androidx.activity.result.contract.ActivityResultContracts.PickMultipleVisualMedia] or
+ * [androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia] Activity Contract.
+ *
+ * @param mediaType type to go into the PickVisualMediaRequest
+ *
+ * @return a PickVisualMediaRequest that contains the given input
+ */
+fun PickVisualMediaRequest(
+    mediaType: VisualMediaType = ImageAndVideo
+) = PickVisualMediaRequest.Builder().setMediaType(mediaType).build()
+
+/**
+ * A request for a
+ * [androidx.activity.result.contract.ActivityResultContracts.PickMultipleVisualMedia] or
+ * [androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia] Activity Contract.
+ */
+class PickVisualMediaRequest internal constructor() {
+
+    var mediaType: VisualMediaType = ImageAndVideo
+        private set
+
+    /**
+     * A builder for constructing [PickVisualMediaRequest] instances.
+     */
+    class Builder {
+
+        private var mediaType: VisualMediaType = ImageAndVideo
+
+        /**
+         * Set the media type for the [PickVisualMediaRequest].
+         *
+         * The type is the mime type to filter by, e.g. `PickVisualMedia.ImageOnly`,
+         * `PickVisualMedia.ImageAndVideo`, `PickVisualMedia.SingleMimeType("image/gif")`
+         *
+         * @param mediaType type to go into the PickVisualMediaRequest
+         * @return This builder.
+         */
+        fun setMediaType(mediaType: VisualMediaType): Builder {
+            this.mediaType = mediaType
+            return this
+        }
+
+        /**
+         * Build the PickVisualMediaRequest specified by this builder.
+         *
+         * @return the newly constructed PickVisualMediaRequest.
+         */
+        fun build(): PickVisualMediaRequest = PickVisualMediaRequest(mediaType).apply {
+            this.mediaType = mediaType
+        }
+    }
+}
diff --git a/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.kt b/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.kt
index 9af89ed..c0634ea 100644
--- a/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.kt
+++ b/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.kt
@@ -22,11 +22,13 @@
 import android.graphics.Bitmap
 import android.net.Uri
 import android.os.Build
+import android.os.ext.SdkExtensions.getExtensionVersion
 import android.provider.ContactsContract
 import android.provider.DocumentsContract
 import android.provider.MediaStore
 import androidx.activity.result.ActivityResult
 import androidx.activity.result.IntentSenderRequest
+import androidx.activity.result.PickVisualMediaRequest
 import androidx.activity.result.contract.ActivityResultContracts.GetMultipleContents.Companion.getClipDataUris
 import androidx.activity.result.contract.ActivityResultContracts.StartIntentSenderForResult.Companion.ACTION_INTENT_SENDER_REQUEST
 import androidx.activity.result.contract.ActivityResultContracts.StartIntentSenderForResult.Companion.EXTRA_SEND_INTENT_EXCEPTION
@@ -257,6 +259,7 @@
             input: Void?
         ): SynchronousResult<Bitmap?>? = null
 
+        @Suppress("DEPRECATION")
         final override fun parseResult(resultCode: Int, intent: Intent?): Bitmap? {
             return intent.takeIf { resultCode == Activity.RESULT_OK }?.getParcelableExtra("data")
         }
@@ -317,6 +320,7 @@
             input: Uri
         ): SynchronousResult<Bitmap?>? = null
 
+        @Suppress("DEPRECATION")
         final override fun parseResult(resultCode: Int, intent: Intent?): Bitmap? {
             return intent.takeIf { resultCode == Activity.RESULT_OK }?.getParcelableExtra("data")
         }
@@ -597,4 +601,185 @@
             return intent.takeIf { resultCode == Activity.RESULT_OK }?.data
         }
     }
+
+    /**
+     * An [ActivityResultContract] to use the photo picker through [MediaStore.ACTION_PICK_IMAGES]
+     * when available, and else rely on ACTION_OPEN_DOCUMENT.
+     *
+     * The input is a [PickVisualMediaRequest].
+     *
+     * The output is a `Uri` when the user has selected a media or `null` when the user hasn't
+     * selected any item. Keep in mind that `Uri` returned by the photo picker isn't writable.
+     *
+     * This can be extended to override [createIntent] if you wish to pass additional
+     * extras to the Intent created by `super.createIntent()`.
+     */
+    open class PickVisualMedia : ActivityResultContract<PickVisualMediaRequest, Uri?>() {
+        companion object {
+            /**
+             * Check if the current device has support for the photo picker by checking the running
+             * Android version or the SDK extension version
+             */
+            @JvmStatic
+            fun isPhotoPickerAvailable(): Boolean {
+                return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU ||
+                    getExtensionVersion(Build.VERSION_CODES.R) >= 2
+            }
+
+            internal fun getVisualMimeType(input: VisualMediaType): String? {
+                return when (input) {
+                    is ImageOnly -> "image/*"
+                    is VideoOnly -> "video/*"
+                    is SingleMimeType -> input.mimeType
+                    is ImageAndVideo -> null
+                }
+            }
+        }
+
+        /**
+         * Represents filter input type accepted by the photo picker.
+         */
+        sealed interface VisualMediaType
+
+        /**
+         * [VisualMediaType] object used to filter images only when using the photo picker.
+         */
+        object ImageOnly : VisualMediaType
+
+        /**
+         * [VisualMediaType] object used to filter video only when using the photo picker.
+         */
+        object VideoOnly : VisualMediaType
+
+        /**
+         * [VisualMediaType] object used to filter images and video when using the photo picker.
+         */
+        object ImageAndVideo : VisualMediaType
+
+        /**
+         * [VisualMediaType] class used to filter a single mime type only when using the photo
+         * picker.
+         */
+        class SingleMimeType(val mimeType: String) : VisualMediaType
+
+        @CallSuper
+        override fun createIntent(context: Context, input: PickVisualMediaRequest): Intent {
+            // Check if Photo Picker is available on the device
+            return if (isPhotoPickerAvailable()) {
+                Intent(MediaStore.ACTION_PICK_IMAGES).apply {
+                    type = getVisualMimeType(input.mediaType)
+                }
+            } else {
+                // For older devices running KitKat and higher and devices running Android 12
+                // and 13 without the SDK extension that includes the Photo Picker, rely on the
+                // ACTION_OPEN_DOCUMENT intent
+                Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
+                    type = getVisualMimeType(input.mediaType)
+
+                    if (type == null) {
+                        // ACTION_OPEN_DOCUMENT requires to set this parameter when launching the
+                        // intent with multiple mime types
+                        type = "*/*"
+                        putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*"))
+                    }
+                }
+            }
+        }
+
+        @Suppress("InvalidNullabilityOverride")
+        final override fun getSynchronousResult(
+            context: Context,
+            input: PickVisualMediaRequest
+        ): SynchronousResult<Uri?>? = null
+
+        final override fun parseResult(resultCode: Int, intent: Intent?): Uri? {
+            return intent.takeIf { resultCode == Activity.RESULT_OK }?.data
+        }
+    }
+
+    /**
+     * An [ActivityResultContract] to use the Photo Picker through [MediaStore.ACTION_PICK_IMAGES]
+     * when available, and else rely on ACTION_OPEN_DOCUMENT.
+     *
+     * The constructor accepts one parameter `maxItems` to limit the number of selectable items when
+     * using the photo picker to return. Keep in mind that this parameter isn't supported on devices
+     * when the photo picker isn't available.
+     *
+     * The input is a [PickVisualMediaRequest].
+     *
+     * The output is a list `Uri` of the selected media. It can be empty if the user hasn't selected
+     * any items. Keep in mind that `Uri` returned by the photo picker aren't writable.
+     *
+     * This can be extended to override [createIntent] if you wish to pass additional
+     * extras to the Intent created by `super.createIntent()`.
+     */
+    @RequiresApi(19)
+    open class PickMultipleVisualMedia(
+        private val maxItems: Int = getMaxItems()
+    ) : ActivityResultContract<PickVisualMediaRequest, List<@JvmSuppressWildcards Uri>>() {
+
+        init {
+            require(maxItems > 1) {
+                "Max items must be higher than 1"
+            }
+        }
+
+        @CallSuper
+        override fun createIntent(context: Context, input: PickVisualMediaRequest): Intent {
+            // Check to see if the photo picker is available
+            return if (PickVisualMedia.isPhotoPickerAvailable()) {
+                Intent(MediaStore.ACTION_PICK_IMAGES).apply {
+                    type = PickVisualMedia.getVisualMimeType(input.mediaType)
+
+                    require(maxItems <= MediaStore.getPickImagesMaxLimit()) {
+                        "Max items must be less or equals MediaStore.getPickImagesMaxLimit()"
+                    }
+
+                    putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxItems)
+                }
+            } else {
+                // For older devices running KitKat and higher and devices running Android 12
+                // and 13 without the SDK extension that includes the Photo Picker, rely on the
+                // ACTION_OPEN_DOCUMENT intent
+                Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
+                    type = PickVisualMedia.getVisualMimeType(input.mediaType)
+                    putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
+
+                    if (type == null) {
+                        // ACTION_OPEN_DOCUMENT requires to set this parameter when launching the
+                        // intent with multiple mime types
+                        type = "*/*"
+                        putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*"))
+                    }
+                }
+            }
+        }
+
+        @Suppress("InvalidNullabilityOverride")
+        final override fun getSynchronousResult(
+            context: Context,
+            input: PickVisualMediaRequest
+        ): SynchronousResult<List<@JvmSuppressWildcards Uri>>? = null
+
+        final override fun parseResult(resultCode: Int, intent: Intent?): List<Uri> {
+            return intent.takeIf {
+                resultCode == Activity.RESULT_OK
+            }?.getClipDataUris() ?: emptyList()
+        }
+
+        internal companion object {
+            /**
+             * The photo picker has a maximum limit of selectable items returned by
+             * [MediaStore.getPickImagesMaxLimit()]. On devices not supporting the photo picker, the
+             * limit is ignored.
+             *
+             * @see MediaStore.EXTRA_PICK_IMAGES_MAX
+             */
+            internal fun getMaxItems() = if (PickVisualMedia.isPhotoPickerAvailable()) {
+                MediaStore.getPickImagesMaxLimit()
+            } else {
+                Integer.MAX_VALUE
+            }
+        }
+    }
 }
diff --git a/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt b/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt
index 11780b3..947be53 100644
--- a/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt
+++ b/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt
@@ -36,11 +36,14 @@
 import androidx.activity.ComponentActivity
 import androidx.activity.result.ActivityResultLauncher
 import androidx.activity.result.IntentSenderRequest
+import androidx.activity.result.PickVisualMediaRequest
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.activity.result.contract.ActivityResultContracts.CaptureVideo
 import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
 import androidx.activity.result.contract.ActivityResultContracts.GetContent
 import androidx.activity.result.contract.ActivityResultContracts.OpenMultipleDocuments
+import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia
+import androidx.activity.result.contract.ActivityResultContracts.PickMultipleVisualMedia
 import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
 import androidx.activity.result.contract.ActivityResultContracts.TakePicture
 import androidx.activity.result.contract.ActivityResultContracts.TakePicturePreview
@@ -77,6 +80,10 @@
         toast("Got image: $uri")
     }
 
+    lateinit var pickVisualMedia: ActivityResultLauncher<PickVisualMediaRequest>
+
+    lateinit var pickMultipleVisualMedia: ActivityResultLauncher<PickVisualMediaRequest>
+
     lateinit var createDocument: ActivityResultLauncher<String>
 
     lateinit var openDocuments: ActivityResultLauncher<Array<String>>
@@ -92,6 +99,17 @@
         super.onCreate(savedInstanceState)
 
         if (android.os.Build.VERSION.SDK_INT >= 19) {
+            pickVisualMedia = registerForActivityResult(PickVisualMedia()) { uri ->
+                toast("Got image: $uri")
+            }
+            pickMultipleVisualMedia =
+                registerForActivityResult(PickMultipleVisualMedia(5)) { uris ->
+                    var media = ""
+                    uris.forEach {
+                        media += "uri: $it \n"
+                    }
+                    toast("Got media files: $media")
+                }
             createDocument = registerForActivityResult(CreateDocument("image/png")) { uri ->
                 toast("Created document: $uri")
             }
@@ -124,10 +142,25 @@
                     val uri = FileProvider.getUriForFile(this@MainActivity, packageName, file)
                     captureVideo.launch(uri)
                 }
-                button("Pick an image") {
+                button("Pick an image (w/ GET_CONTENT)") {
                     getContent.launch("image/*")
                 }
                 if (android.os.Build.VERSION.SDK_INT >= 19) {
+                    button("Pick an image (w/ photo picker)") {
+                        pickVisualMedia.launch(
+                            PickVisualMediaRequest(PickVisualMedia.ImageOnly)
+                        )
+                    }
+                    button("Pick a GIF (w/ photo picker)") {
+                        pickVisualMedia.launch(
+                            PickVisualMediaRequest(PickVisualMedia.SingleMimeType("image/gif"))
+                        )
+                    }
+                    button("Pick 5 visual media max (w/ photo picker)") {
+                        pickMultipleVisualMedia.launch(
+                            PickVisualMediaRequest(PickVisualMedia.ImageAndVideo)
+                        )
+                    }
                     button("Create document") {
                         createDocument.launch("Temp")
                     }
diff --git a/appcompat/appcompat/api/current.txt b/appcompat/appcompat/api/current.txt
index 26a352f..b17e49a 100644
--- a/appcompat/appcompat/api/current.txt
+++ b/appcompat/appcompat/api/current.txt
@@ -224,6 +224,7 @@
     method public androidx.appcompat.app.ActionBar? getSupportActionBar();
     method public android.content.Intent? getSupportParentActivityIntent();
     method public void onCreateSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder);
+    method protected void onLocalesChanged(androidx.core.os.LocaleListCompat);
     method public final boolean onMenuItemSelected(int, android.view.MenuItem);
     method protected void onNightModeChanged(int);
     method public void onPrepareSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder);
@@ -261,6 +262,8 @@
     method public static androidx.appcompat.app.AppCompatDelegate create(android.content.Context, android.app.Activity, androidx.appcompat.app.AppCompatCallback?);
     method public abstract android.view.View! createView(android.view.View?, String!, android.content.Context, android.util.AttributeSet);
     method public abstract <T extends android.view.View> T! findViewById(@IdRes int);
+    method @AnyThread public static androidx.core.os.LocaleListCompat getApplicationLocales();
+    method public android.content.Context? getContextForDelegate();
     method public static int getDefaultNightMode();
     method public abstract androidx.appcompat.app.ActionBarDrawerToggle.Delegate? getDrawerToggleDelegate();
     method public int getLocalNightMode();
@@ -280,6 +283,7 @@
     method public abstract void onStart();
     method public abstract void onStop();
     method public abstract boolean requestWindowFeature(int);
+    method public static void setApplicationLocales(androidx.core.os.LocaleListCompat);
     method public static void setCompatVectorFromResourcesEnabled(boolean);
     method public abstract void setContentView(android.view.View!);
     method public abstract void setContentView(@LayoutRes int);
@@ -339,6 +343,12 @@
     method protected android.view.View? createView(android.content.Context!, String!, android.util.AttributeSet!);
   }
 
+  public final class AppLocalesMetadataHolderService extends android.app.Service {
+    ctor public AppLocalesMetadataHolderService();
+    method public static android.content.pm.ServiceInfo getServiceInfo(android.content.Context) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public android.os.IBinder onBind(android.content.Intent);
+  }
+
 }
 
 package androidx.appcompat.graphics.drawable {
diff --git a/appcompat/appcompat/api/public_plus_experimental_current.txt b/appcompat/appcompat/api/public_plus_experimental_current.txt
index 26a352f..b17e49a 100644
--- a/appcompat/appcompat/api/public_plus_experimental_current.txt
+++ b/appcompat/appcompat/api/public_plus_experimental_current.txt
@@ -224,6 +224,7 @@
     method public androidx.appcompat.app.ActionBar? getSupportActionBar();
     method public android.content.Intent? getSupportParentActivityIntent();
     method public void onCreateSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder);
+    method protected void onLocalesChanged(androidx.core.os.LocaleListCompat);
     method public final boolean onMenuItemSelected(int, android.view.MenuItem);
     method protected void onNightModeChanged(int);
     method public void onPrepareSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder);
@@ -261,6 +262,8 @@
     method public static androidx.appcompat.app.AppCompatDelegate create(android.content.Context, android.app.Activity, androidx.appcompat.app.AppCompatCallback?);
     method public abstract android.view.View! createView(android.view.View?, String!, android.content.Context, android.util.AttributeSet);
     method public abstract <T extends android.view.View> T! findViewById(@IdRes int);
+    method @AnyThread public static androidx.core.os.LocaleListCompat getApplicationLocales();
+    method public android.content.Context? getContextForDelegate();
     method public static int getDefaultNightMode();
     method public abstract androidx.appcompat.app.ActionBarDrawerToggle.Delegate? getDrawerToggleDelegate();
     method public int getLocalNightMode();
@@ -280,6 +283,7 @@
     method public abstract void onStart();
     method public abstract void onStop();
     method public abstract boolean requestWindowFeature(int);
+    method public static void setApplicationLocales(androidx.core.os.LocaleListCompat);
     method public static void setCompatVectorFromResourcesEnabled(boolean);
     method public abstract void setContentView(android.view.View!);
     method public abstract void setContentView(@LayoutRes int);
@@ -339,6 +343,12 @@
     method protected android.view.View? createView(android.content.Context!, String!, android.util.AttributeSet!);
   }
 
+  public final class AppLocalesMetadataHolderService extends android.app.Service {
+    ctor public AppLocalesMetadataHolderService();
+    method public static android.content.pm.ServiceInfo getServiceInfo(android.content.Context) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public android.os.IBinder onBind(android.content.Intent);
+  }
+
 }
 
 package androidx.appcompat.graphics.drawable {
diff --git a/appcompat/appcompat/api/restricted_current.txt b/appcompat/appcompat/api/restricted_current.txt
index d5a987e..29b83c6 100644
--- a/appcompat/appcompat/api/restricted_current.txt
+++ b/appcompat/appcompat/api/restricted_current.txt
@@ -245,6 +245,7 @@
     method public androidx.appcompat.app.ActionBar? getSupportActionBar();
     method public android.content.Intent? getSupportParentActivityIntent();
     method public void onCreateSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder);
+    method protected void onLocalesChanged(androidx.core.os.LocaleListCompat);
     method public final boolean onMenuItemSelected(int, android.view.MenuItem);
     method protected void onNightModeChanged(@androidx.appcompat.app.AppCompatDelegate.NightMode int);
     method public void onPrepareSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder);
@@ -282,6 +283,8 @@
     method public static androidx.appcompat.app.AppCompatDelegate create(android.content.Context, android.app.Activity, androidx.appcompat.app.AppCompatCallback?);
     method public abstract android.view.View! createView(android.view.View?, String!, android.content.Context, android.util.AttributeSet);
     method public abstract <T extends android.view.View> T! findViewById(@IdRes int);
+    method @AnyThread public static androidx.core.os.LocaleListCompat getApplicationLocales();
+    method public android.content.Context? getContextForDelegate();
     method @androidx.appcompat.app.AppCompatDelegate.NightMode public static int getDefaultNightMode();
     method public abstract androidx.appcompat.app.ActionBarDrawerToggle.Delegate? getDrawerToggleDelegate();
     method @androidx.appcompat.app.AppCompatDelegate.NightMode public int getLocalNightMode();
@@ -301,6 +304,7 @@
     method public abstract void onStart();
     method public abstract void onStop();
     method public abstract boolean requestWindowFeature(int);
+    method public static void setApplicationLocales(androidx.core.os.LocaleListCompat);
     method public static void setCompatVectorFromResourcesEnabled(boolean);
     method public abstract void setContentView(android.view.View!);
     method public abstract void setContentView(@LayoutRes int);
@@ -363,6 +367,12 @@
     method protected android.view.View? createView(android.content.Context!, String!, android.util.AttributeSet!);
   }
 
+  public final class AppLocalesMetadataHolderService extends android.app.Service {
+    ctor public AppLocalesMetadataHolderService();
+    method public static android.content.pm.ServiceInfo getServiceInfo(android.content.Context) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public android.os.IBinder onBind(android.content.Intent);
+  }
+
   @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class WindowDecorActionBar extends androidx.appcompat.app.ActionBar implements androidx.appcompat.widget.ActionBarOverlayLayout.ActionBarVisibilityCallback {
     ctor public WindowDecorActionBar(android.app.Activity!, boolean);
     ctor public WindowDecorActionBar(android.app.Dialog!);
diff --git a/appcompat/appcompat/src/androidTest/AndroidManifest.xml b/appcompat/appcompat/src/androidTest/AndroidManifest.xml
index 5b766cc..a5c8fe7 100644
--- a/appcompat/appcompat/src/androidTest/AndroidManifest.xml
+++ b/appcompat/appcompat/src/androidTest/AndroidManifest.xml
@@ -26,6 +26,15 @@
         android:supportsRtl="true"
         android:theme="@style/Theme.AppCompat">
 
+        <service
+            android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
+            android:enabled="false"
+            android:exported="false">
+            <meta-data
+                android:name="autoStoreLocales"
+                android:value="false" />
+        </service>
+
         <activity
             android:name="androidx.appcompat.app.AppCompatActivity"/>
 
@@ -334,6 +343,40 @@
 
         <activity
             android:name="androidx.appcompat.widget.TooltipCompatTestActivity" />
+        <activity android:name="androidx.appcompat.app.LocalesUpdateActivity"/>
+
+        <activity
+            android:name="androidx.appcompat.app.LocalesConfigChangesActivity"
+            android:configChanges="locale|layoutDirection"/>
+
+        <activity
+            android:name="androidx.appcompat.app.LocalesCustomApplyOverrideConfigurationActivity" />
+
+        <activity android:name="androidx.appcompat.app.LocalesDialogFragment"/>
+
+        <activity android:name="androidx.appcompat.app.LocalesCustomAttachBaseContextActivity"/>
+
+        <activity
+            android:name="androidx.appcompat.app.LocalesRotateDoesNotRecreateActivity"
+            android:configChanges="orientation|screenSize"/>
+
+        <activity android:name="androidx.appcompat.app.LocalesActivityA"/>
+
+        <activity android:name="androidx.appcompat.app.LocalesActivityB"/>
+
+        <activity
+            android:name="androidx.appcompat.app.LocalesConfigChangesActivityA"
+            android:configChanges="locale|layoutDirection"/>
+
+        <activity
+            android:name="androidx.appcompat.app.LocalesConfigChangesActivityB"
+            android:configChanges="locale|layoutDirection"/>
+
+        <activity
+            android:name="androidx.appcompat.app.LocalesConfigChangesActivityWithoutLayoutDirection"
+            android:configChanges="locale"/>
+
+        <activity android:name="androidx.appcompat.app.LocalesLateOnCreateActivity"/>
 
     </application>
 
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesActivityA.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesActivityA.java
new file mode 100644
index 0000000..5719451
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesActivityA.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ * 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.appcompat.app;
+
+/**
+ * An activity for locales with a unique class name.
+ */
+public class LocalesActivityA extends LocalesUpdateActivity {}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesActivityB.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesActivityB.java
new file mode 100644
index 0000000..b327efb
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesActivityB.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ * 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.appcompat.app;
+
+/**
+ * An activity for locales with a unique class name.
+ */
+public class LocalesActivityB extends LocalesUpdateActivity {}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesChangeWhenInBackground.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesChangeWhenInBackground.kt
new file mode 100644
index 0000000..9ae3adda
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesChangeWhenInBackground.kt
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ * 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.appcompat.app
+
+import android.content.Intent
+import androidx.appcompat.testutils.LocalesActivityTestRule
+import androidx.appcompat.testutils.LocalesUtils.CUSTOM_LOCALE_LIST
+import androidx.appcompat.testutils.LocalesUtils.assertConfigurationLocalesEquals
+import androidx.appcompat.testutils.LocalesUtils.setLocalesAndWaitForRecreate
+import androidx.core.os.LocaleListCompat
+import androidx.lifecycle.Lifecycle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.testutils.LifecycleOwnerUtils.waitUntilState
+import junit.framework.TestCase.assertNotSame
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+//  setApplicationLocales
+@SdkSuppress(maxSdkVersion = 31)
+class LocalesChangeWhenInBackground {
+    @get:Rule
+    val rule = LocalesActivityTestRule(LocalesUpdateActivity::class.java)
+    private var systemLocales = LocaleListCompat.getEmptyLocaleList()
+
+    @Before
+    fun setUp() {
+        // Since no locales are applied as of now, current configuration will have system
+        // locales.
+        systemLocales = LocalesUpdateActivity.getConfigLocales(
+            rule.activity.resources.configuration)
+    }
+
+    @Test
+    fun testLocalesChangeWhenInBackground() {
+
+        val instrumentation = InstrumentationRegistry.getInstrumentation()
+        val firstActivity = rule.activity
+        assertConfigurationLocalesEquals(systemLocales, firstActivity)
+
+        // Start a new Activity, so that the original Activity goes into the background
+        val intent = Intent(firstActivity, AppCompatActivity::class.java).apply {
+            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        }
+        val secondActivity = instrumentation.startActivitySync(intent) as AppCompatActivity
+        assertConfigurationLocalesEquals(systemLocales, secondActivity)
+
+        // Now change the locales for the foreground activity
+        val recreatedSecond = setLocalesAndWaitForRecreate(
+            secondActivity,
+            CUSTOM_LOCALE_LIST
+        )
+
+        // Now finish the foreground activity and wait until it is destroyed,
+        // allowing the recreated activity to come to the foreground
+        instrumentation.runOnMainSync { recreatedSecond.finish() }
+        waitUntilState(recreatedSecond, Lifecycle.State.DESTROYED)
+
+        // Assert that the recreated Activity becomes resumed
+        instrumentation.waitForIdleSync()
+        assertNotSame(rule.activity, firstActivity)
+        waitUntilState(rule.activity, Lifecycle.State.RESUMED)
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesActivity.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesActivity.java
new file mode 100644
index 0000000..d7c757e
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesActivity.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ * 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.appcompat.app;
+
+/**
+ * An activity that handles locales configuration changes.
+ */
+public class LocalesConfigChangesActivity extends LocalesUpdateActivity { }
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesActivityA.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesActivityA.java
new file mode 100644
index 0000000..c6b0d8b
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesActivityA.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ * 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.appcompat.app;
+
+/**
+ * An activity that handles locales configuration changes.
+ */
+public class LocalesConfigChangesActivityA extends LocalesUpdateActivity {}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesActivityB.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesActivityB.java
new file mode 100644
index 0000000..c59c33b
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesActivityB.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ * 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.appcompat.app;
+
+/**
+ * An activity that handles locales configuration changes.
+ */
+public class LocalesConfigChangesActivityB extends LocalesUpdateActivity {}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesActivityWithoutLayoutDirection.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesActivityWithoutLayoutDirection.java
new file mode 100644
index 0000000..77d7bfb
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesActivityWithoutLayoutDirection.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2022 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.appcompat.app;
+
+/**
+ * An activity that handles locales configuration changes and does not handle layoutDirection
+ * configChanges.
+ */
+public class LocalesConfigChangesActivityWithoutLayoutDirection extends LocalesUpdateActivity { }
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesTestCase.kt
new file mode 100644
index 0000000..a4aff79
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesTestCase.kt
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ * 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.appcompat.app
+
+import androidx.appcompat.testutils.LocalesUtils
+import androidx.appcompat.testutils.LocalesUtils.CUSTOM_LOCALE_LIST
+import androidx.appcompat.testutils.LocalesUtils.assertConfigurationLocalesEquals
+import androidx.appcompat.testutils.LocalesUtils.setLocales
+import androidx.core.os.LocaleListCompat
+import androidx.lifecycle.Lifecycle
+import androidx.test.core.app.ActivityScenario
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import androidx.testutils.withActivity
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNull
+import org.junit.Before
+import org.junit.Test
+
+@LargeTest
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+//  setApplicationLocales
+@SdkSuppress(maxSdkVersion = 31)
+class LocalesConfigChangesTestCase() {
+    private lateinit var scenario: ActivityScenario<LocalesConfigChangesActivity>
+    private var systemLocales = LocaleListCompat.getEmptyLocaleList()
+    private var expectedLocales = LocaleListCompat.getEmptyLocaleList()
+
+    @Before
+    fun setup() {
+        LocalesUtils.initCustomLocaleList()
+        // By default we'll set the apps to use system locales, which allows us to make better
+        // assumptions in the tests below.
+        // Launch the test activity.
+        scenario = ActivityScenario.launch(LocalesConfigChangesActivity::class.java)
+        scenario.onActivity {
+            // Since no locales are applied as of now, current configuration will have system
+            // locales.
+            systemLocales = LocalesUpdateActivity.getConfigLocales(it.resources.configuration)
+            // expected locales is an overlay of custom and system locales.
+            expectedLocales = LocalesUpdateActivity.overlayCustomAndSystemLocales(
+                CUSTOM_LOCALE_LIST, systemLocales)
+        }
+    }
+
+    @Test
+    fun testOnConfigurationChangeCalledWhileStarted() {
+        scenario.moveToState(Lifecycle.State.RESUMED)
+
+        // Set locales to CUSTOM_LOCALE_LIST.
+        scenario.onActivity { setLocales(CUSTOM_LOCALE_LIST) }
+        // Assert that the onConfigurationChange was called with a new correct config.
+        scenario.onActivity {
+            val lastConfig = it.lastConfigurationChangeAndClear
+            assertConfigurationLocalesEquals(
+                expectedLocales,
+                lastConfig!!
+            )
+        }
+
+        // Set locales back to system locales.
+        scenario.onActivity { setLocales(LocaleListCompat.getEmptyLocaleList()) }
+        // Assert that the onConfigurationChange was called with a new correct config.
+        scenario.onActivity {
+            val lastConfig = it.lastConfigurationChangeAndClear
+            assertConfigurationLocalesEquals(
+                systemLocales, lastConfig!!
+            )
+        }
+    }
+
+    @Test
+    fun testOnConfigurationChangeCalledWhileStopped() {
+        scenario.moveToState(Lifecycle.State.RESUMED)
+        scenario.moveToState(Lifecycle.State.CREATED)
+
+        // Set locales to CUSTOM_LOCALE_LIST.
+        scenario.onActivity { setLocales(CUSTOM_LOCALE_LIST) }
+        // Assert that the onConfigurationChange was called with a new correct config.
+        scenario.onActivity {
+            val lastConfig = it.lastConfigurationChangeAndClear
+            assertConfigurationLocalesEquals(
+                expectedLocales,
+                lastConfig!!
+            )
+        }
+
+        // Set locales back to system locales.
+        scenario.onActivity { setLocales(LocaleListCompat.getEmptyLocaleList()) }
+        // Assert that the onConfigurationChange was called with a new correct config.
+        scenario.onActivity {
+            val lastConfig = it.lastConfigurationChangeAndClear
+            assertConfigurationLocalesEquals(
+                systemLocales, lastConfig!!
+            )
+        }
+    }
+
+    @Test
+    fun testOnConfigurationChangeNotCalledWhileDestroyed() {
+        scenario.moveToState(Lifecycle.State.RESUMED)
+
+        lateinit var activity: LocalesConfigChangesActivity
+        scenario.onActivity { activity = it }
+
+        scenario.moveToState(Lifecycle.State.DESTROYED)
+
+        // Clear any previous config changes.
+        activity.lastConfigurationChangeAndClear
+
+        // Set locales to CUSTOM_LOCALE_LIST.
+        setLocales(CUSTOM_LOCALE_LIST)
+        // Assert that the onConfigurationChange was not called with a new correct config.
+        assertNull(activity.lastConfigurationChangeAndClear)
+
+        // Set locales back to system locales.
+        setLocales(LocaleListCompat.getEmptyLocaleList())
+        // Assert that the onConfigurationChange was not called with a new correct config.
+        assertNull(activity.lastConfigurationChangeAndClear)
+    }
+
+    @Test
+    fun testResourcesUpdated() {
+        // Set locales to CUSTOM_LOCALE_LIST.
+        scenario.onActivity { setLocales(CUSTOM_LOCALE_LIST) }
+
+        // Assert that the Activity resources configuration was updated.
+        assertConfigurationLocalesEquals(
+            expectedLocales,
+            scenario.withActivity { this }
+        )
+
+        // Set locales back to system locales.
+        scenario.onActivity { setLocales(LocaleListCompat.getEmptyLocaleList()) }
+
+        // Assert that the Activity resources configuration was updated.
+        assertConfigurationLocalesEquals(
+            systemLocales,
+            scenario.withActivity { this }
+        )
+    }
+
+    @Test
+    fun testOnLocalesChangedCalled() {
+        // Set locales to CUSTOM_LOCALE_LIST.
+        scenario.onActivity { setLocales(CUSTOM_LOCALE_LIST) }
+        // Assert that the Activity received a new value.
+        assertEquals(
+            expectedLocales,
+            scenario.withActivity { lastLocalesAndReset }
+        )
+
+        // Set locales back to system locales.
+        scenario.onActivity { setLocales(LocaleListCompat.getEmptyLocaleList()) }
+        // Assert that the Activity received a new value.
+        assertEquals(systemLocales, scenario.withActivity { lastLocalesAndReset })
+    }
+
+    @After
+    fun cleanup() {
+        // Reset the system locales.
+        if (scenario.state != Lifecycle.State.DESTROYED) {
+            scenario.onActivity { setLocales(LocaleListCompat.getEmptyLocaleList()) }
+        }
+        LocalesUpdateActivity.teardown()
+        scenario.close()
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesWithoutLayoutDirectionTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesWithoutLayoutDirectionTestCase.kt
new file mode 100644
index 0000000..c20886a
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesConfigChangesWithoutLayoutDirectionTestCase.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2022 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("deprecation")
+
+package androidx.appcompat.app
+
+import androidx.appcompat.testutils.LocalesUtils
+import androidx.core.os.LocaleListCompat
+import androidx.lifecycle.Lifecycle
+import androidx.test.core.app.ActivityScenario
+import androidx.test.filters.SdkSuppress
+import junit.framework.Assert.assertNull
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+//  setApplicationLocales
+@SdkSuppress(maxSdkVersion = 31)
+class LocalesConfigChangesWithoutLayoutDirectionTestCase {
+    private lateinit var scenario: ActivityScenario<
+        LocalesConfigChangesActivityWithoutLayoutDirection>
+    private var systemLocales = LocaleListCompat.getEmptyLocaleList()
+    private var expectedLocales = LocaleListCompat.getEmptyLocaleList()
+
+    @Before
+    fun setup() {
+        LocalesUtils.initCustomLocaleList()
+        // By default we'll set the apps to use system locales, which allows us to make better
+        // assumptions in the tests below.
+        // Launch the test activity.
+        scenario =
+            ActivityScenario.launch(LocalesConfigChangesActivityWithoutLayoutDirection::class.java)
+        scenario.onActivity {
+            // Since no locales are applied as of now, current configuration will have system
+            // locales.
+            systemLocales = LocalesUpdateActivity.getConfigLocales(it.resources.configuration)
+            // expected locales is an overlay of custom and system locales.
+            expectedLocales = LocalesUpdateActivity.overlayCustomAndSystemLocales(
+                LocalesUtils.CUSTOM_LOCALE_LIST, systemLocales
+            )
+        }
+    }
+
+    @Test
+    fun testOnConfigurationChangeNotCalledWhileStarted() {
+        scenario.moveToState(Lifecycle.State.RESUMED)
+
+        // Set locales to CUSTOM_LOCALE_LIST.
+        scenario.onActivity { LocalesUtils.setLocales(LocalesUtils.CUSTOM_LOCALE_LIST) }
+        // Assert that the onConfigurationChange was called with a new correct config.
+        scenario.onActivity {
+            // the call should not have reached the LocalesUpdateActivity.onConfigurationChange()
+            // because the manifest entry for LocalesConfigChangesActivityWithoutLayoutDirection
+            // only handles locale and not layoutDir.
+            assertNull(it.lastConfigurationChangeAndClear)
+            LocalesUtils.assertConfigurationLocalesEquals(
+                expectedLocales,
+                it.resources.configuration!!
+            )
+        }
+    }
+
+    @After
+    fun teardown() {
+        LocalesUpdateActivity.teardown()
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesCustomApplyOverrideConfigurationActivity.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesCustomApplyOverrideConfigurationActivity.java
new file mode 100644
index 0000000..e39c081
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesCustomApplyOverrideConfigurationActivity.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ * 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.appcompat.app;
+
+import android.content.Context;
+import android.content.res.Configuration;
+
+import androidx.annotation.RequiresApi;
+
+/**
+ * An activity that has a customized fontScale, set before onCreate().
+ */
+@RequiresApi(17)
+public class LocalesCustomApplyOverrideConfigurationActivity extends LocalesUpdateActivity {
+    public static final float CUSTOM_FONT_SCALE = 4.24f;
+
+    @Override
+    protected void attachBaseContext(Context newBase) {
+        super.attachBaseContext(newBase);
+
+        Configuration config = new Configuration();
+        config.fontScale = CUSTOM_FONT_SCALE;
+        super.applyOverrideConfiguration(config);
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesCustomApplyOverrideConfigurationTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesCustomApplyOverrideConfigurationTestCase.kt
new file mode 100644
index 0000000..27c3d16
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesCustomApplyOverrideConfigurationTestCase.kt
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ * 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.appcompat.app
+
+import android.content.res.Configuration
+import androidx.appcompat.app.LocalesCustomApplyOverrideConfigurationActivity.CUSTOM_FONT_SCALE
+import androidx.appcompat.testutils.LocalesActivityTestRule
+import androidx.appcompat.testutils.LocalesUtils.CUSTOM_LOCALE_LIST
+import androidx.appcompat.testutils.LocalesUtils.setLocalesAndWaitForRecreate
+import androidx.appcompat.testutils.NightModeUtils
+import androidx.appcompat.testutils.NightModeUtils.assertConfigurationNightModeEquals
+import androidx.core.os.LocaleListCompat
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import org.junit.Assert.assertEquals
+import org.junit.Rule
+import org.junit.Test
+
+/**
+ * This is one approach to customize Activity's configuration that's used in google3.
+ */
+@LargeTest
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+// setApplicationLocales
+@SdkSuppress(minSdkVersion = 17, maxSdkVersion = 31)
+class LocalesCustomApplyOverrideConfigurationTestCase() {
+
+    @get:Rule
+    val activityRule = LocalesActivityTestRule(
+        LocalesCustomApplyOverrideConfigurationActivity::class.java
+    )
+
+    @Test
+    @Suppress("DEPRECATION")
+    fun testNightModeIsMaintainedOnLocalesChange() {
+        NightModeUtils.setNightModeAndWaitForRecreate(
+            activityRule,
+            AppCompatDelegate.MODE_NIGHT_YES,
+            NightModeUtils.NightSetMode.LOCAL
+        )
+        assertConfigurationNightModeEquals(
+            Configuration.UI_MODE_NIGHT_YES,
+            activityRule.activity.resources.configuration
+        )
+        setLocalesAndWaitForRecreate(activityRule, CUSTOM_LOCALE_LIST)
+        // Check that the custom configuration properties are maintained
+        assertConfigurationNightModeEquals(
+            Configuration.UI_MODE_NIGHT_YES,
+            activityRule.activity.resources.configuration
+        )
+        setLocalesAndWaitForRecreate(activityRule, LocaleListCompat.getEmptyLocaleList())
+    }
+
+    @Test
+    fun testFontScaleIsMaintained() {
+        // Check that the custom configuration properties are maintained
+        val config = activityRule.activity.resources.configuration
+        assertEquals(CUSTOM_FONT_SCALE, config.fontScale)
+    }
+
+    @Test
+    fun testFontScaleIsMaintainedOnLocalesChange() {
+        // Set locales to CUSTOM_LOCALE_LIST.
+        setLocalesAndWaitForRecreate(activityRule, CUSTOM_LOCALE_LIST)
+        // Check that the custom configuration properties are maintained.
+        val config = activityRule.activity.resources.configuration
+        assertEquals(CUSTOM_FONT_SCALE, config.fontScale)
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesCustomAttachBaseContextActivity.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesCustomAttachBaseContextActivity.java
new file mode 100644
index 0000000..9f929e5b
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesCustomAttachBaseContextActivity.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ * 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.appcompat.app;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.Build;
+
+/**
+ * An activity with customized configuration.
+ */
+public class LocalesCustomAttachBaseContextActivity extends LocalesUpdateActivity {
+    public static final float CUSTOM_FONT_SCALE = 4.24f;
+
+    @Override
+    protected void attachBaseContext(Context newBase) {
+        super.attachBaseContext(useCustomConfig(newBase));
+    }
+
+    private Context useCustomConfig(Context context) {
+        if (Build.VERSION.SDK_INT >= 24) {
+            Configuration config = new Configuration();
+            config.fontScale = CUSTOM_FONT_SCALE;
+            return context.createConfigurationContext(config);
+        } else {
+            Resources res = context.getResources();
+            Configuration config = new Configuration(res.getConfiguration());
+            config.fontScale = CUSTOM_FONT_SCALE;
+            res.updateConfiguration(config, res.getDisplayMetrics());
+            return context;
+        }
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesCustomAttachBaseContextTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesCustomAttachBaseContextTestCase.kt
new file mode 100644
index 0000000..9215bf4
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesCustomAttachBaseContextTestCase.kt
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ * 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.appcompat.app
+
+import android.content.res.Configuration
+import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
+import androidx.appcompat.app.NightModeCustomAttachBaseContextActivity.CUSTOM_FONT_SCALE
+import androidx.appcompat.testutils.LocalesActivityTestRule
+import androidx.appcompat.testutils.LocalesUtils.CUSTOM_LOCALE_LIST
+import androidx.appcompat.testutils.LocalesUtils.setLocalesAndWaitForRecreate
+import androidx.appcompat.testutils.NightModeUtils.NightSetMode
+import androidx.appcompat.testutils.NightModeUtils.assertConfigurationNightModeEquals
+import androidx.appcompat.testutils.NightModeUtils.setNightModeAndWaitForRecreate
+import androidx.core.os.LocaleListCompat
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+@LargeTest
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+// setApplicationLocales
+@SdkSuppress(maxSdkVersion = 31)
+class LocalesCustomAttachBaseContextTestCase() {
+
+    @get:Rule
+    val activityRule = LocalesActivityTestRule(
+        LocalesCustomAttachBaseContextActivity::class.java
+    )
+
+    @Before
+    fun setUp() {
+        AppCompatDelegate.setApplicationLocales(LocaleListCompat.getEmptyLocaleList())
+    }
+
+    @Test
+    @Suppress("DEPRECATION")
+    fun testNightModeIsMaintainedOnLocalesChange() {
+        setNightModeAndWaitForRecreate(
+            activityRule,
+            MODE_NIGHT_YES,
+            NightSetMode.LOCAL
+        )
+        assertConfigurationNightModeEquals(
+            Configuration.UI_MODE_NIGHT_YES,
+            activityRule.activity.resources.configuration
+        )
+        setLocalesAndWaitForRecreate(activityRule, CUSTOM_LOCALE_LIST)
+        // Check that the custom configuration properties are maintained
+        assertConfigurationNightModeEquals(
+            Configuration.UI_MODE_NIGHT_YES,
+            activityRule.activity.resources.configuration
+        )
+    }
+
+    @Test
+    fun testFontScaleIsMaintained() {
+        // Check that the custom configuration properties are maintained.
+        val config = activityRule.activity.resources.configuration
+        assertEquals(CUSTOM_FONT_SCALE, config.fontScale)
+    }
+
+    @Test
+    fun testFontScaleIsMaintainedOnLocalesChange() {
+        // Set locales to CUSTOM_LOCALE_LIST.
+        setLocalesAndWaitForRecreate(activityRule, CUSTOM_LOCALE_LIST)
+        // Check that the custom configuration properties are maintained.
+        val config = activityRule.activity.resources.configuration
+        assertEquals(CUSTOM_FONT_SCALE, config.fontScale)
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesForegroundDialogTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesForegroundDialogTestCase.kt
new file mode 100644
index 0000000..7ced0ff
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesForegroundDialogTestCase.kt
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ * 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.appcompat.app
+
+import androidx.appcompat.testutils.LocalesActivityTestRule
+import androidx.appcompat.testutils.LocalesUtils.CUSTOM_LOCALE_LIST
+import androidx.appcompat.testutils.LocalesUtils.assertConfigurationLocalesEquals
+import androidx.appcompat.testutils.LocalesUtils.setLocalesAndWaitForRecreate
+import androidx.core.os.LocaleListCompat
+import androidx.lifecycle.Lifecycle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import androidx.testutils.LifecycleOwnerUtils.waitUntilState
+import junit.framework.TestCase.assertNotSame
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+// setApplicationLocales
+@SdkSuppress(maxSdkVersion = 31)
+class LocalesForegroundDialogTestCase {
+    @get:Rule
+    val rule = LocalesActivityTestRule(LocalesUpdateActivity::class.java)
+    private var baseLocales = LocaleListCompat.getEmptyLocaleList()
+
+    @Before
+    fun setUp() {
+        AppCompatDelegate.setApplicationLocales(LocaleListCompat.getEmptyLocaleList())
+        baseLocales = LocalesUpdateActivity.getConfigLocales(rule.activity.resources.configuration)
+    }
+
+    @Test
+    fun testLocalesChangeWithForegroundDialog() {
+        val firstActivity = rule.activity
+        assertConfigurationLocalesEquals(baseLocales, firstActivity)
+
+        // Open a dialog on top of the activity.
+        rule.runOnUiThread {
+            val frag = TestDialogFragment.newInstance()
+            frag.show(firstActivity.supportFragmentManager, "dialog")
+        }
+
+        // Now change the locales for the foreground activity.
+        setLocalesAndWaitForRecreate(
+            firstActivity,
+            CUSTOM_LOCALE_LIST
+        )
+
+        // Ensure that it was recreated.
+        assertNotSame(rule.activity, firstActivity)
+        waitUntilState(rule.activity, Lifecycle.State.RESUMED)
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesLateOnCreateActivity.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesLateOnCreateActivity.java
new file mode 100644
index 0000000..6466e41
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesLateOnCreateActivity.java
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ * 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.appcompat.app;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.LocaleList;
+
+import androidx.core.os.LocaleListCompat;
+
+import java.util.Locale;
+
+/**
+ * An activity with systemLocales replaced with some customised locales for testing.
+ */
+public class LocalesLateOnCreateActivity extends LocalesUpdateActivity {
+
+    public static LocaleListCompat DEFAULT_LOCALE_LIST;
+    public static LocaleListCompat TEST_LOCALE_LIST;
+    public static LocaleListCompat EXPECTED_LOCALE_LIST;
+
+    @Override
+    public void onCreate(Bundle bundle) {
+        // Override locales so that AppCompat attempts to re-apply during onCreate().
+
+        if (Build.VERSION.SDK_INT >= 21) {
+            DEFAULT_LOCALE_LIST = LocaleListCompat.forLanguageTags(
+                    Locale.US.toLanguageTag() + "," + Locale.CHINESE.toLanguageTag());
+            TEST_LOCALE_LIST = LocaleListCompat.forLanguageTags(
+                    Locale.CANADA_FRENCH.toLanguageTag() + ","
+                            + Locale.US.toLanguageTag());
+            EXPECTED_LOCALE_LIST = LocaleListCompat.forLanguageTags(
+                    Locale.CANADA_FRENCH.toLanguageTag() + ","
+                            + Locale.US.toLanguageTag() + "," + Locale.CHINESE.toLanguageTag());
+        } else {
+            DEFAULT_LOCALE_LIST = LocaleListCompat.create(Locale.US);
+            TEST_LOCALE_LIST = LocaleListCompat.create(Locale.CANADA_FRENCH);
+            EXPECTED_LOCALE_LIST = LocaleListCompat.create(Locale.CANADA_FRENCH);
+        }
+        disableAutomaticLocales(getApplicationContext());
+
+        super.onCreate(bundle);
+    }
+
+    private static void setLocales(LocaleListCompat locales, Context context) {
+        Configuration conf = context.getResources().getConfiguration();
+        if (Build.VERSION.SDK_INT >= 24) {
+            conf.setLocales(LocaleList.forLanguageTags(locales.toLanguageTags()));
+        } else if (Build.VERSION.SDK_INT >= 17) {
+            conf.setLocale(locales.get(0));
+        } else {
+            conf.locale = locales.get(0);
+        }
+        // updateConfiguration is required to make the configuration change stick.
+        // updateConfiguration must be called before any use of the actual Resources.
+        context.getResources().updateConfiguration(conf,
+                context.getResources().getDisplayMetrics());
+    }
+
+    /**
+     * Ensures the context does not use system locales, instead uses the DEFAULT_LOCALE_LIST
+     *
+     * <p>This must be called before a Context's Resources are used for the first time. {@code
+     * Activity.onCreate} is a great place to call {@code disableAutomaticLocales(this)}
+     */
+    public static void disableAutomaticLocales(Context context) {
+        setLocales(DEFAULT_LOCALE_LIST, context);
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesLateOnCreateTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesLateOnCreateTestCase.kt
new file mode 100644
index 0000000..13968ee
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesLateOnCreateTestCase.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ * 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.appcompat.app
+
+import androidx.appcompat.app.LocalesLateOnCreateActivity.DEFAULT_LOCALE_LIST
+import androidx.appcompat.app.LocalesLateOnCreateActivity.EXPECTED_LOCALE_LIST
+import androidx.appcompat.app.LocalesLateOnCreateActivity.TEST_LOCALE_LIST
+import androidx.appcompat.testutils.LocalesActivityTestRule
+import androidx.appcompat.testutils.LocalesUtils.assertConfigurationLocalesEquals
+import androidx.appcompat.testutils.LocalesUtils.setLocalesAndWaitForRecreate
+import androidx.lifecycle.Lifecycle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import androidx.testutils.LifecycleOwnerUtils.waitUntilState
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+//  setApplicationLocales
+@SdkSuppress(maxSdkVersion = 31)
+class LocalesLateOnCreateTestCase {
+
+    @get:Rule
+    val activityRule = LocalesActivityTestRule(LocalesLateOnCreateActivity::class.java)
+
+    @Test
+    fun testActivityRecreateLoop() {
+        // Activity should be able to reach fully resumed state in default locales.
+        waitUntilState(activityRule.activity, Lifecycle.State.RESUMED)
+        assertConfigurationLocalesEquals(
+            DEFAULT_LOCALE_LIST,
+            activityRule.activity.resources.configuration
+        )
+
+        // Simulate the user set locales, which should force an activity recreate().
+        setLocalesAndWaitForRecreate(
+            activityRule,
+            TEST_LOCALE_LIST
+        )
+
+        // Activity should be able to reach fully resumed state again.
+        waitUntilState(activityRule.activity, Lifecycle.State.RESUMED)
+
+        // The requested locales should have been set during attachBaseContext().
+        assertConfigurationLocalesEquals(
+            EXPECTED_LOCALE_LIST,
+            activityRule.activity.resources.configuration
+        )
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesPersistTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesPersistTestCase.kt
new file mode 100644
index 0000000..0470ce5f
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesPersistTestCase.kt
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2022 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("deprecation")
+
+package androidx.appcompat.app
+
+import android.content.Intent
+import androidx.appcompat.testutils.LocalesActivityTestRule
+import androidx.appcompat.testutils.LocalesUtils.CUSTOM_LOCALE_LIST
+import androidx.appcompat.testutils.LocalesUtils.assertConfigurationLocalesEquals
+import androidx.appcompat.testutils.LocalesUtils.setLocalesAndWaitForRecreate
+import androidx.core.os.LocaleListCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.platform.app.InstrumentationRegistry
+import junit.framework.Assert.assertNull
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+// setApplicationLocales
+@SdkSuppress(maxSdkVersion = 31)
+class LocalesPersistTestCase() {
+    @get:Rule
+    val rule = LocalesActivityTestRule(LocalesUpdateActivity::class.java)
+    private var systemLocales = LocaleListCompat.getEmptyLocaleList()
+    private var expectedLocales = LocaleListCompat.getEmptyLocaleList()
+
+    @Before
+    fun setUp() {
+        // Since no locales are applied as of now, current configuration will have system
+        // locales.
+        systemLocales = LocalesUpdateActivity.getConfigLocales(
+            rule.activity.resources.configuration
+        )
+        expectedLocales = LocalesUpdateActivity.overlayCustomAndSystemLocales(
+            CUSTOM_LOCALE_LIST, systemLocales
+        )
+    }
+
+    /**
+     * This test verifies that the locales persist in storage when a metadata entry for
+     * "autoStoreLocale" is provided as an opt-in.
+     * To replicate the scenario of app-startup a method resetStaticRequestedAndStoredLocales()
+     * is called to clear out the static storage of locales. The flow of the test is:
+     * setApplicationLocales is called on the firstActivity and it is recreated as recreatedFirst.
+     * Now the locales must have been stored and the static storage would also hold these. Then
+     * we clear out the static storage and create a new activity secondActivity by using an intent
+     * and because the static storage was already clear the activity should sync locales from
+     * storage and start up in the app-specific locales.
+     */
+    @Test
+    fun testLocalesAppliedInNewActivityAfterStaticStorageCleared() {
+        // mimics opting in to "autoStoreLocales"
+        AppCompatDelegate.setIsAutoStoreLocalesOptedIn(true)
+
+        val instrumentation = InstrumentationRegistry.getInstrumentation()
+        val firstActivity = rule.activity
+        assertConfigurationLocalesEquals(systemLocales, firstActivity)
+
+        // Now change the locales for the activity
+        val recreatedFirst = setLocalesAndWaitForRecreate(
+            firstActivity,
+            CUSTOM_LOCALE_LIST
+        )
+
+        assertConfigurationLocalesEquals(expectedLocales, recreatedFirst)
+
+        // clear out static storage so that, when a new activity starts it syncs locales
+        // from storage.
+        AppCompatDelegate.resetStaticRequestedAndStoredLocales()
+        // verify that the static locales were cleared out.
+        assertNull(AppCompatDelegate.getRequestedAppLocales())
+
+        // Start a new Activity, so that the original Activity goes into the background
+        val intent = Intent(recreatedFirst, AppCompatActivity::class.java).apply {
+            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        }
+        val secondActivity = instrumentation.startActivitySync(intent) as AppCompatActivity
+
+        // assert that the new activity started with the app-specific locales after reading them
+        // from storage.
+        assertConfigurationLocalesEquals(expectedLocales, secondActivity)
+    }
+
+    @Test
+    fun testNewActivityCreatedWhenNoAppLocalesExist() {
+        val instrumentation = InstrumentationRegistry.getInstrumentation()
+        val firstActivity = rule.activity
+        assertConfigurationLocalesEquals(systemLocales, firstActivity)
+
+        // Start a new Activity, so that the original Activity goes into the background
+        val intent = Intent(firstActivity, AppCompatActivity::class.java).apply {
+            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        }
+        val secondActivity = instrumentation.startActivitySync(intent) as AppCompatActivity
+
+        // assert that the new activity started with the systemLocales.
+        assertConfigurationLocalesEquals(systemLocales, secondActivity)
+    }
+
+    @After
+    fun teardown() {
+        rule.runOnUiThread {
+            // clean-up
+            AppCompatDelegate.setApplicationLocales(LocaleListCompat.getEmptyLocaleList())
+            // setting auto storage opt-in to false
+            AppCompatDelegate.setIsAutoStoreLocalesOptedIn(false)
+        }
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesRotateDoesNotRecreateActivity.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesRotateDoesNotRecreateActivity.java
new file mode 100644
index 0000000..14efcde
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesRotateDoesNotRecreateActivity.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ * 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.appcompat.app;
+
+public class LocalesRotateDoesNotRecreateActivity extends LocalesUpdateActivity {}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesRotateDoesNotRecreateActivityTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesRotateDoesNotRecreateActivityTestCase.kt
new file mode 100644
index 0000000..ef28708
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesRotateDoesNotRecreateActivityTestCase.kt
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ * 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.appcompat.app
+
+import androidx.appcompat.Orientation
+import androidx.appcompat.testutils.LocalesActivityTestRule
+import androidx.appcompat.testutils.LocalesUtils.CUSTOM_LOCALE_LIST
+import androidx.appcompat.testutils.LocalesUtils.assertConfigurationLocalesEquals
+import androidx.appcompat.testutils.LocalesUtils.setLocalesAndWaitForRecreate
+import androidx.appcompat.withOrientation
+import androidx.core.os.LocaleListCompat
+import androidx.lifecycle.Lifecycle
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import androidx.testutils.LifecycleOwnerUtils
+import org.junit.After
+import org.junit.Assert.assertNotSame
+import org.junit.Assert.assertSame
+import org.junit.Rule
+import org.junit.Test
+
+@LargeTest
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+// setApplicationLocales
+@SdkSuppress(minSdkVersion = 18, maxSdkVersion = 31)
+class LocalesRotateDoesNotRecreateActivityTestCase() {
+
+    private val instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+
+    @get:Rule
+    val activityRule: LocalesActivityTestRule<LocalesRotateDoesNotRecreateActivity> =
+        LocalesActivityTestRule(
+            LocalesRotateDoesNotRecreateActivity::class.java,
+            initialTouchMode = false,
+            // Let the test method launch its own activity so that we can ensure it's RESUMED.
+            launchActivity = false
+        )
+
+    @Test
+    fun testRotateDoesNotRecreateActivity() {
+        // Set locales to CUSTOM_LOCALE_LIST and wait for state RESUMED.
+        val initialActivity = activityRule.launchActivity(null)
+        var systemLocales = LocalesUpdateActivity.getConfigLocales(
+            initialActivity.resources.configuration)
+        LifecycleOwnerUtils.waitUntilState(initialActivity, Lifecycle.State.RESUMED)
+        setLocalesAndWaitForRecreate(initialActivity, CUSTOM_LOCALE_LIST)
+
+        val localesActivity = activityRule.activity
+        val config = localesActivity.resources.configuration
+
+        // On API level 26 and below, the configuration object is going to be identical
+        // across configuration changes, so we need to pull the orientation value now.
+        val orientation = config.orientation
+        val expectedLocales = LocalesUpdateActivity.overlayCustomAndSystemLocales(
+            CUSTOM_LOCALE_LIST, systemLocales)
+        // Assert that the current Activity has the new locales.
+        assertConfigurationLocalesEquals(expectedLocales, config)
+
+        // Now rotate the device. This should NOT result in a lifecycle event, just a call to
+        // onConfigurationChanged.
+        localesActivity.resetOnConfigurationChange()
+        device.withOrientation(Orientation.LEFT) {
+            instrumentation.waitForIdleSync()
+            localesActivity.expectOnConfigurationChange(5000)
+
+            // Assert that we got the same activity and thus it was not recreated.
+            val rotatedLocalesActivity = activityRule.activity
+            val rotatedConfig = rotatedLocalesActivity.resources.configuration
+            assertSame(localesActivity, rotatedLocalesActivity)
+            assertConfigurationLocalesEquals(expectedLocales, rotatedConfig)
+
+            // On API level 26 and below, the configuration object is going to be identical
+            // across configuration changes, so we need to compare against the cached value.
+            assertNotSame(orientation, rotatedConfig.orientation)
+        }
+    }
+
+    @After
+    fun teardown() {
+        device.setOrientationNatural()
+        // setOrientationNatural may need some time rotate orientation to natural, so we wait for
+        // the operation to end for 5000ms.
+        device.waitForIdle(/* timeout= */5000)
+
+        // Clean up
+        activityRule.runOnUiThread {
+            AppCompatDelegate.setApplicationLocales(LocaleListCompat.getEmptyLocaleList())
+        }
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesRotateRecreatesActivityWithConfigTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesRotateRecreatesActivityWithConfigTestCase.kt
new file mode 100644
index 0000000..d5f5fa1
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesRotateRecreatesActivityWithConfigTestCase.kt
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ * 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.appcompat.app
+
+import android.app.Activity
+import android.app.Instrumentation
+import androidx.appcompat.Orientation
+import androidx.appcompat.testutils.LocalesActivityTestRule
+import androidx.appcompat.testutils.LocalesUtils.CUSTOM_LOCALE_LIST
+import androidx.appcompat.testutils.LocalesUtils.assertConfigurationLocalesEquals
+import androidx.appcompat.testutils.LocalesUtils.setLocalesAndWaitForRecreate
+import androidx.appcompat.withOrientation
+import androidx.core.os.LocaleListCompat
+import androidx.lifecycle.Lifecycle
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import androidx.testutils.LifecycleOwnerUtils
+import org.junit.After
+import org.junit.Assert.assertNotEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNotSame
+import org.junit.Rule
+import org.junit.Test
+
+@LargeTest
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+// setApplicationLocales
+@SdkSuppress(minSdkVersion = 18, maxSdkVersion = 31)
+class LocalesRotateRecreatesActivityWithConfigTestCase() {
+
+    private val instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+    private var systemLocales = LocaleListCompat.getEmptyLocaleList()
+    @get:Rule
+    public val activityRule: LocalesActivityTestRule<LocalesUpdateActivity> =
+        LocalesActivityTestRule(
+            LocalesUpdateActivity::class.java,
+            initialTouchMode = false,
+            // Let the test method launch its own activity so that we can ensure it's RESUMED.
+            launchActivity = false
+        )
+
+    @After
+    public fun teardown() {
+        device.setOrientationNatural()
+        device.waitForIdle(/* timeout= */5000)
+
+        // Clean up after the default mode test.
+
+        activityRule.runOnUiThread {
+            AppCompatDelegate.setApplicationLocales(LocaleListCompat.getEmptyLocaleList())
+        }
+    }
+
+    @Test
+    public fun testRotateRecreatesActivityWithConfig() {
+        // Set locales to CUSTOM_LOCALE_LIST and wait for state RESUMED.
+        val initialActivity = activityRule.launchActivity(null)
+        LifecycleOwnerUtils.waitUntilState(initialActivity, Lifecycle.State.RESUMED)
+        systemLocales = LocalesUpdateActivity.getConfigLocales(activityRule.activity.resources
+            .configuration)
+
+        setLocalesAndWaitForRecreate(initialActivity, CUSTOM_LOCALE_LIST)
+
+        val localesActivity = activityRule.activity
+        val config = localesActivity.resources.configuration
+
+        // On API level 26 and below, the configuration object is going to be identical
+        // across configuration changes, so we need to pull the orientation value now.
+        val orientation = config.orientation
+
+        // Assert that the current Activity has the expected locales.
+        assertConfigurationLocalesEquals(LocalesUpdateActivity.overlayCustomAndSystemLocales(
+            CUSTOM_LOCALE_LIST, systemLocales), config)
+
+        // Now rotate the device. This should result in an onDestroy lifecycle event.
+        localesActivity.resetOnDestroy()
+        rotateDeviceAndWaitForRecreate(localesActivity) {
+            localesActivity.expectOnDestroy(/* timeout= */ 5000)
+
+            // Assert that we got a different activity and thus it was recreated.
+            val rotatedLocalesActivity = activityRule.activity
+            val rotatedConfig = rotatedLocalesActivity.resources.configuration
+            assertNotSame(localesActivity, rotatedLocalesActivity)
+            assertConfigurationLocalesEquals(
+                LocalesUpdateActivity.overlayCustomAndSystemLocales(CUSTOM_LOCALE_LIST,
+                    systemLocales),
+                rotatedConfig
+            )
+
+            // On API level 26 and below, the configuration object is going to be identical
+            // across configuration changes, so we need to compare against the cached value.
+            assertNotSame(orientation, rotatedConfig.orientation)
+        }
+    }
+
+    private fun rotateDeviceAndWaitForRecreate(activity: Activity, doThis: () -> Unit) {
+        val monitor = Instrumentation.ActivityMonitor(activity::class.java.name, /* result= */
+            null, /* block= */false)
+        instrumentation.addMonitor(monitor)
+
+        device.withOrientation(Orientation.LEFT) {
+            // Wait for the activity to be recreated after rotation
+            var count = 0
+            var lastActivity: Activity? = activity
+            while ((lastActivity == null || activity == lastActivity) && count < 5) {
+                // If this times out, it will return null.
+                lastActivity = monitor.waitForActivityWithTimeout(/* timeout= */ 1000L)
+                count++
+            }
+            instrumentation.waitForIdleSync()
+
+            // Ensure that we didn't time out
+            assertNotNull("Activity was not recreated within 5000ms", lastActivity)
+            assertNotEquals(
+                "Activity was not recreated within 5000ms", activity, lastActivity
+            )
+            doThis()
+        }
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesSetUsingFrameworkApiTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesSetUsingFrameworkApiTestCase.kt
new file mode 100644
index 0000000..b8696c4
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesSetUsingFrameworkApiTestCase.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2022 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("deprecation")
+
+package androidx.appcompat.app
+
+import android.os.Build
+import android.os.LocaleList
+import androidx.annotation.RequiresApi
+import androidx.appcompat.testutils.LocalesActivityTestRule
+import androidx.appcompat.testutils.LocalesUtils
+import androidx.appcompat.testutils.LocalesUtils.CUSTOM_LOCALE_LIST
+import androidx.appcompat.testutils.LocalesUtils.assertConfigurationLocalesEquals
+import androidx.core.os.LocaleListCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import junit.framework.Assert.assertEquals
+import junit.framework.Assert.assertNull
+import org.junit.After
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+// setApplicationLocales. The minSdkVersion should be set to 33 after API bump.
+@SdkSuppress(minSdkVersion = 32)
+class LocalesSetUsingFrameworkApiTestCase {
+    @get:Rule
+    val rule = LocalesActivityTestRule(LocalesUpdateActivity::class.java)
+    private var systemLocales = LocaleListCompat.getEmptyLocaleList()
+    private var expectedLocales = LocaleListCompat.getEmptyLocaleList()
+
+    @RequiresApi(33)
+    @Before
+    fun setUp() {
+        assumeTrue(
+            "Requires API version >=T", Build.VERSION.SDK_INT >= 33
+        )
+
+        // setting the app to follow system.
+        AppCompatDelegate.Api33Impl.localeManagerSetApplicationLocales(
+            AppCompatDelegate.getLocaleManagerForApplication(),
+            LocaleList.getEmptyLocaleList()
+        )
+        // Since no locales are applied as of now, current configuration will have system
+        // locales.
+        systemLocales = LocalesUpdateActivity.getConfigLocales(
+            rule.activity.resources.configuration
+        )
+        expectedLocales = LocalesUpdateActivity.overlayCustomAndSystemLocales(
+            LocalesUtils.CUSTOM_LOCALE_LIST, systemLocales
+        )
+    }
+
+    /**
+     * Verifies that for API version >=T the AppCompatDelegate.setApplicationLocales() call
+     * is redirected to the framework API and the locales are applied successfully.
+     */
+    @Test
+    @RequiresApi(33)
+    fun testSetApplicationLocales_postT_frameworkApiCalled() {
+        val firstActivity = rule.activity
+        assertConfigurationLocalesEquals(systemLocales, firstActivity)
+
+        assertEquals(
+            LocaleListCompat.getEmptyLocaleList(),
+            AppCompatDelegate.getApplicationLocales()
+        )
+        assertNull(AppCompatDelegate.getRequestedAppLocales())
+
+        // Now change the locales for the activity
+        val recreatedFirst = LocalesUtils.setLocalesAndWaitForRecreate(
+            firstActivity,
+            CUSTOM_LOCALE_LIST
+        )
+
+        assertEquals(
+            CUSTOM_LOCALE_LIST,
+            AppCompatDelegate.getApplicationLocales()
+        )
+        // check that the locales were set using the framework API
+        assertEquals(
+            CUSTOM_LOCALE_LIST.toLanguageTags(),
+            AppCompatDelegate.Api33Impl.localeManagerGetApplicationLocales(
+                AppCompatDelegate.getLocaleManagerForApplication()
+            ).toLanguageTags()
+        )
+        // check locales are applied successfully
+        assertConfigurationLocalesEquals(expectedLocales, recreatedFirst)
+        // check that the override was not done by AndroidX, but by the framework
+        assertNull(AppCompatDelegate.getRequestedAppLocales())
+    }
+
+    @RequiresApi(33)
+    @After
+    fun teardown() {
+        if (!(Build.VERSION.SDK_INT >= 33)) {
+            return
+        }
+        // clearing locales from framework. setting the app to follow system.
+        AppCompatDelegate.Api33Impl.localeManagerSetApplicationLocales(
+            AppCompatDelegate.getLocaleManagerForApplication(),
+            LocaleList.getEmptyLocaleList()
+        )
+    }
+}
\ No newline at end of file
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesStackedHandlingTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesStackedHandlingTestCase.kt
new file mode 100644
index 0000000..a8cb155
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesStackedHandlingTestCase.kt
@@ -0,0 +1,367 @@
+/*
+ * 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.
+ * 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("deprecation")
+
+package androidx.appcompat.app
+
+import android.app.Activity
+import android.app.Instrumentation
+import android.app.Instrumentation.ActivityMonitor
+import android.content.Intent
+import android.os.Handler
+import android.os.Looper
+import androidx.appcompat.testutils.LocalesUtils
+import androidx.appcompat.testutils.LocalesUtils.CUSTOM_LOCALE_LIST
+import androidx.appcompat.testutils.LocalesUtils.assertConfigurationLocalesEquals
+import androidx.core.os.LocaleListCompat
+import androidx.lifecycle.Lifecycle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.testutils.LifecycleOwnerUtils.waitUntilState
+import junit.framework.Assert.assertNotNull
+import junit.framework.Assert.assertNotSame
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+// setApplicationLocales
+@SdkSuppress(maxSdkVersion = 31)
+class LocalesStackedHandlingTestCase {
+
+    @Before
+    fun setUp() {
+        LocalesUtils.initCustomLocaleList()
+    }
+
+    /**
+     * Regression test for the following scenario:
+     *
+     * If you have a stack of activities which includes one with android:configChanges="locale" and
+     * android:configChanges="layoutDirection" and you call AppCompatDelegate.setApplicationLocales
+     * it can cause other activities to not be recreated.
+     *
+     * Eg:
+     * - Activity A DOESN'T intercept locales changes and layoutDirection changes in manifest
+     * - Activity B DOESN'T intercept locales changes and layoutDirection changes in manifest
+     * - Activity C DOES intercept both locales and layoutDirection changes in manifest
+     *
+     * Here is your stack : A > B > C (C on top)
+     *
+     * Call AppCompatDelegate.setApplicationLocales with a new mode on activity C. Activity C
+     * receives the change in onConfigurationChanged but there is a good chance that activity A
+     * and/or B were not recreated.
+     */
+    @Test
+    fun testLocalesWithStackedActivities() {
+        val instr = InstrumentationRegistry.getInstrumentation()
+        val result = Instrumentation.ActivityResult(0, Intent())
+        val monitorA = ActivityMonitor(LocalesActivityA::class.java.name, result, false)
+        val monitorB = ActivityMonitor(LocalesActivityB::class.java.name, result, false)
+        val monitorC = ActivityMonitor(
+            LocalesConfigChangesActivity::class.java.name,
+            result, false
+        )
+        instr.addMonitor(monitorA)
+        instr.addMonitor(monitorB)
+        instr.addMonitor(monitorC)
+
+        instr.runOnMainSync {
+            AppCompatDelegate.setApplicationLocales(LocaleListCompat.getEmptyLocaleList())
+        }
+
+        // Start activity A.
+        instr.startActivitySync(
+            Intent(instr.context, LocalesActivityA::class.java).apply {
+                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                putExtra(LocalesUpdateActivity.KEY_TITLE, "A")
+            }
+        )
+
+        // From activity A, start activity B.
+        val activityA = monitorA.waitForActivityWithTimeout(/* timeout= */ 3000)
+            as LocalesUpdateActivity
+        assertNotNull(activityA)
+        activityA.startActivity(
+            Intent(instr.context, LocalesActivityB::class.java).apply {
+                putExtra(LocalesUpdateActivity.KEY_TITLE, "B")
+            }
+        )
+
+        var systemLocales = LocalesUpdateActivity.getConfigLocales(
+            activityA.resources.configuration
+        )
+
+        // Activity A is hidden, wait for it to stop.
+        waitUntilState(activityA, Lifecycle.State.CREATED)
+
+        // From activity B, start activity C.
+        val activityB =
+            monitorB.waitForActivityWithTimeout(/* timeout= */ 3000) as LocalesUpdateActivity
+        assertNotNull(activityB)
+        activityB.startActivity(
+            Intent(instr.context, LocalesConfigChangesActivity::class.java).apply {
+                putExtra(LocalesUpdateActivity.KEY_TITLE, "C")
+            }
+        )
+
+        // Activity B is hidden, wait for it to stop.
+        waitUntilState(activityB, Lifecycle.State.CREATED)
+
+        // apply CUSTOM_LOCALE_LIST
+        val activityC =
+            monitorC.waitForActivityWithTimeout(/* timeout= */ 3000) as LocalesUpdateActivity
+        assertNotNull(activityC)
+        activityC.runOnUiThread {
+            AppCompatDelegate.setApplicationLocales(CUSTOM_LOCALE_LIST)
+        }
+
+        // Activity C should receive a configuration change.
+        activityC.expectOnConfigurationChange(/* timeout= */ 3000)
+
+        // Activities A and B should recreate() in the background.
+        val activityA2 = expectRecreate(monitorA, activityA) as LocalesUpdateActivity
+        val activityB2 = expectRecreate(monitorB, activityB) as LocalesUpdateActivity
+
+        var expectedLocales = LocalesUpdateActivity.overlayCustomAndSystemLocales(
+            CUSTOM_LOCALE_LIST, systemLocales
+        )
+        // Activity C should have received a locales configuration change.
+        listOf(activityC, activityA2, activityB2).forEach { activity ->
+            activityC.runOnUiThread {
+                assertConfigurationLocalesEquals(
+                    "Activity ${activity.title}'s effective configuration has locales set",
+                    expectedLocales,
+                    activityC.effectiveConfiguration!!
+                )
+            }
+        }
+    }
+
+    /**
+     * Regression test for the following scenario:
+     *
+     * If you have a stack of activities where every activity has `android:configChanges="locale"`
+     * and android:configChanges="layoutDirection" and you call
+     * [AppCompatDelegate.setApplicationLocales] from thread other than the top activity,
+     * then it can cause the bottom activity to not receive `onConfigurationChanged`.
+     *
+     * Eg:
+     * - Activity A DOES intercept locales and layoutDirection changes in manifest
+     * - Activity B DOES intercept locales and layoutDirection changes in manifest
+     * - Activity C DOES intercept locales and layoutDirection changes in manifest
+     *
+     * Here is your stack : A > B > C (C on top)
+     *
+     * Call [AppCompatDelegate.setApplicationLocales] with a new mode on activity C (but not
+     * directly
+     * from this activity, ex with RX AndroidSchedulers.mainThread or an handler). Activity C
+     * receives both `onConfigurationChanged` and `onLocalesChanged`, but activities A and B
+     * may not receive either callback or change their configurations.
+     *
+     * Process:
+     * 1. A > B > C > setApplicationLocales YES
+     * 2. Go back to A (B & C destroyed) > B > C > setApplicationLocales NO (wrong config for A)
+     * 3. repeat (YES/NO/YES/NO...)
+     */
+    @Test
+    fun testLocalesWithStackedActivitiesAndNavigation() {
+        val instr = InstrumentationRegistry.getInstrumentation()
+        val result = Instrumentation.ActivityResult(0, Intent())
+        val monitorA = ActivityMonitor(
+            LocalesConfigChangesActivity::class.java.name,
+            result, false
+        )
+        val monitorB = ActivityMonitor(
+            LocalesConfigChangesActivityA::class.java.name,
+            result, false
+        )
+        val monitorC = ActivityMonitor(
+            LocalesConfigChangesActivityB::class.java.name,
+            result, false
+        )
+        instr.addMonitor(monitorA)
+        instr.addMonitor(monitorB)
+        instr.addMonitor(monitorC)
+
+        instr.runOnMainSync {
+            AppCompatDelegate.setApplicationLocales(LocaleListCompat.getEmptyLocaleList())
+        }
+
+        // Start activity A.
+        instr.startActivitySync(
+            Intent(instr.context, LocalesConfigChangesActivity::class.java).apply {
+                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                putExtra(LocalesUpdateActivity.KEY_TITLE, "A")
+            }
+        )
+
+        // From activity A, start activity B.
+        val activityA =
+            monitorA.waitForActivityWithTimeout(/* timeout= */ 3000) as LocalesUpdateActivity
+        assertNotNull("Activity A started within 3000ms", activityA)
+        activityA.startActivity(
+            Intent(instr.context, LocalesConfigChangesActivityA::class.java).apply {
+                putExtra(LocalesUpdateActivity.KEY_TITLE, "B")
+            }
+        )
+
+        var systemLocales = LocalesUpdateActivity.getConfigLocales(
+            activityA.resources.configuration
+        )
+
+        // Activity A is hidden, wait for it to stop.
+        waitUntilState(activityA, Lifecycle.State.CREATED)
+
+        // From activity B, start activity C.
+        val activityB =
+            monitorB.waitForActivityWithTimeout(/* timeout= */ 3000) as LocalesUpdateActivity
+        assertNotNull("Activity B started within 3000ms", activityB)
+        activityB.startActivity(
+            Intent(instr.context, LocalesConfigChangesActivityB::class.java).apply {
+                putExtra(LocalesUpdateActivity.KEY_TITLE, "C")
+            }
+        )
+
+        // Activity B is hidden, wait for it to stop.
+        waitUntilState(activityB, Lifecycle.State.CREATED)
+
+        // Wait for activity C to start.
+        val activityC =
+            monitorC.waitForActivityWithTimeout(/* timeout= */ 3000) as LocalesUpdateActivity
+        assertNotNull("Activity C started within 3000ms", activityC)
+
+        // Change locales from a non-UI thread.
+        Handler(Looper.getMainLooper()).post {
+            AppCompatDelegate.setApplicationLocales(CUSTOM_LOCALE_LIST)
+        }
+
+        // Activities A, B, and C should all receive configuration changes.
+        listOf(activityA, activityB, activityC).forEach { activity ->
+            activity.expectOnConfigurationChange(/* timeout= */ 3000)
+        }
+
+        var expectedLocales = LocalesUpdateActivity.overlayCustomAndSystemLocales(
+            CUSTOM_LOCALE_LIST, systemLocales
+        )
+
+        // Activities A, B, and C should have all received the new configuration.
+        listOf(activityA, activityB, activityC).forEach { activity ->
+            activity.runOnUiThread {
+                assertConfigurationLocalesEquals(
+                    "Activity ${activity.title}'s effective configuration has locales set",
+                    expectedLocales,
+                    activity.effectiveConfiguration!!
+                )
+            }
+        }
+
+        // Tear down activities C and B, in that order.
+        listOf(activityC, activityB).forEach { activity ->
+            activity.runOnUiThread {
+                activity.finish()
+            }
+            waitUntilState(activity, Lifecycle.State.DESTROYED)
+        }
+
+        // Activity A is in the foreground, wait for it to resume.
+        waitUntilState(activityA, Lifecycle.State.RESUMED)
+
+        // From activity A, start activity B again.
+        activityA.startActivity(
+            Intent(instr.context, LocalesConfigChangesActivityA::class.java).apply {
+                putExtra(LocalesUpdateActivity.KEY_TITLE, "B2")
+            }
+        )
+
+        // Activity A is hidden, wait for it to stop.
+        waitUntilState(activityA, Lifecycle.State.CREATED)
+
+        // From activity B, start activity C. Double-check the return, since the monitor could
+        // trigger on Activity B's lifecycle if the platform does something unexpected.
+        val activityB2 =
+            monitorB.waitForActivityWithTimeout(/* timeout= */ 3000) as LocalesUpdateActivity
+        assertNotSame("Monitor responded to activity B2 lifecycle", activityB, activityB2)
+        assertNotNull("Activity B2 started within 3000ms", activityB2)
+        activityB2.startActivity(
+            Intent(instr.context, LocalesConfigChangesActivityB::class.java).apply {
+                putExtra(LocalesUpdateActivity.KEY_TITLE, "C2")
+            }
+        )
+
+        // Activity B is hidden, wait for it to stop.
+        waitUntilState(activityB2, Lifecycle.State.CREATED)
+
+        // Wait for activity C to start. Double-check the return.
+        val activityC2 =
+            monitorC.waitForActivityWithTimeout(/* timeout= */ 3000) as LocalesUpdateActivity
+        assertNotSame("Monitor responded to Activity C2 lifecycle", activityC, activityC2)
+        assertNotNull("Activity C2 started within 3000ms", activityC2)
+
+        // Prepare activities A, B, and C to track configuration changes.
+        listOf(activityA, activityB2, activityC2).forEach { activity ->
+            activity.resetOnConfigurationChange()
+        }
+
+        // Change locales again from a non-UI thread.
+        Handler(Looper.getMainLooper()).post {
+            AppCompatDelegate.setApplicationLocales(LocaleListCompat.getEmptyLocaleList())
+        }
+
+        // Activities A, B, and C should all receive configuration changes.
+        listOf(activityA, activityB2, activityC2).forEach { activity ->
+            activity.expectOnConfigurationChange(/* timeout= */ 3000)
+        }
+
+        // Activities A, B, and C should have all received the new configuration.
+        listOf(activityA, activityB2, activityC2).forEach { activity ->
+            activity.runOnUiThread {
+                assertConfigurationLocalesEquals(
+                    "Activity ${activity.title}'s effective configuration has locales set",
+                    systemLocales,
+                    activity.effectiveConfiguration!!
+                )
+            }
+        }
+    }
+
+    private fun expectRecreate(monitor: ActivityMonitor, activity: Activity): Activity {
+        // The documentation says "Block until an Activity is created that matches this monitor."
+        // This statement is true, but there are some other true statements like: "Block until an
+        // Activity is destroyed" or "Block until an Activity is resumed"...
+        var activityResult: Activity?
+        synchronized(monitor) {
+            do {
+                // this call will release synchronization monitor's monitor
+                activityResult = monitor.waitForActivityWithTimeout(/* timeout= */ 3000)
+            } while (activityResult != null && activityResult == activity)
+        }
+
+        assertNotNull("Recreated activity " + activity.title, activityResult)
+        return activityResult!!
+    }
+
+    @After
+    fun teardown() {
+        LocalesUpdateActivity.teardown()
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesSyncToFrameworkTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesSyncToFrameworkTestCase.kt
new file mode 100644
index 0000000..618356731
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesSyncToFrameworkTestCase.kt
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2022 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("deprecation")
+
+package androidx.appcompat.app
+
+import android.content.ComponentName
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.os.Build
+import android.os.LocaleList
+import androidx.annotation.RequiresApi
+import androidx.appcompat.testutils.LocalesActivityTestRule
+import androidx.appcompat.testutils.LocalesUtils.CUSTOM_LOCALE_LIST
+import androidx.appcompat.testutils.LocalesUtils.assertConfigurationLocalesEquals
+import androidx.core.os.LocaleListCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.platform.app.InstrumentationRegistry
+import junit.framework.Assert.assertEquals
+import junit.framework.Assert.assertNull
+import org.junit.After
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Test case to verify app-locales sync to framework on Version upgrade from Pre T to T.
+ */
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+// setApplicationLocales
+// This test should only be run for API version T and hence after API bump both
+// minSdkVersion and maxSdkVersion should be set to 33.
+@SdkSuppress(minSdkVersion = 32, maxSdkVersion = 33)
+class LocalesSyncToFrameworkTestCase {
+    @get:Rule
+    val rule = LocalesActivityTestRule(LocalesUpdateActivity::class.java)
+    private var systemLocales = LocaleListCompat.getEmptyLocaleList()
+    private var expectedLocales = LocaleListCompat.getEmptyLocaleList()
+    private lateinit var appLocalesComponent: ComponentName
+    private val instrumentation = InstrumentationRegistry.getInstrumentation()
+
+    @RequiresApi(33)
+    @Before
+    fun setUp() {
+        assumeTrue("Requires API version >=T", Build.VERSION.SDK_INT >= 33)
+        // setting the app to follow system.
+        AppCompatDelegate.Api33Impl.localeManagerSetApplicationLocales(
+            AppCompatDelegate.getLocaleManagerForApplication(),
+            LocaleList.getEmptyLocaleList()
+        )
+
+        // Since no locales are applied as of now, current configuration will have system
+        // locales.
+        systemLocales = LocalesUpdateActivity.getConfigLocales(
+            rule.activity.resources.configuration
+        )
+        expectedLocales = LocalesUpdateActivity.overlayCustomAndSystemLocales(
+            CUSTOM_LOCALE_LIST, systemLocales
+        )
+
+        appLocalesComponent = ComponentName(
+            instrumentation.context,
+            AppLocalesStorageHelper.APP_LOCALES_META_DATA_HOLDER_SERVICE_NAME
+        )
+    }
+
+    @RequiresApi(33)
+    @Test
+    fun testAutoSync_preTToPostT_syncsSuccessfully() {
+        val firstActivity = rule.activity
+
+        // activity is following the system and the requested locales are null.
+        assertConfigurationLocalesEquals(systemLocales, firstActivity)
+        assertNull(AppCompatDelegate.getRequestedAppLocales())
+
+        val context = instrumentation.context
+
+        // persist some app locales in storage, mimicking locales set using the backward
+        // compatibility API
+        AppCompatDelegate.setIsAutoStoreLocalesOptedIn(true)
+        AppLocalesStorageHelper.persistLocales(context, CUSTOM_LOCALE_LIST.toLanguageTags())
+
+        // explicitly disable appLocalesComponent that acts as a marker to represent that the
+        // locales has been synced so that when a new activity is created the locales are
+        // synced from storage
+        context.packageManager.setComponentEnabledSetting(
+            appLocalesComponent,
+            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+            /* flags= */ PackageManager.DONT_KILL_APP
+        )
+
+        // resetting static storage represents a fresh app start up.
+        AppCompatDelegate.resetStaticRequestedAndStoredLocales()
+
+        // Start a new Activity, so that the original Activity goes into the background
+        val intent = Intent(firstActivity, AppCompatActivity::class.java).apply {
+            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        }
+        val secondActivity = instrumentation.startActivitySync(intent) as AppCompatActivity
+
+        // wait for locales to get synced, stop execution of the current thread for the
+        // timeout period
+        Thread.sleep(/* timeout= */ 1000)
+
+        // check that the locales were set using the framework API and they have been synced
+        // successfully
+        assertEquals(
+            CUSTOM_LOCALE_LIST.toLanguageTags(),
+            AppCompatDelegate.Api33Impl.localeManagerGetApplicationLocales(
+                AppCompatDelegate.getLocaleManagerForApplication()
+            ).toLanguageTags()
+        )
+        // check that the activity has the app specific locales
+        assertConfigurationLocalesEquals(expectedLocales, secondActivity)
+        // check that the override was not done by AndroidX, but by the framework
+        assertNull(AppCompatDelegate.getRequestedAppLocales())
+        // check that the synced marker was set to true
+        assertEquals(
+            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+            context.packageManager.getComponentEnabledSetting(appLocalesComponent)
+        )
+
+        AppCompatDelegate.setIsAutoStoreLocalesOptedIn(false)
+    }
+
+    @After
+    @RequiresApi(33)
+    fun teardown() {
+        if (!(Build.VERSION.SDK_INT >= 33)) {
+            return
+        }
+        val context = instrumentation.context
+
+        AppCompatDelegate.setIsAutoStoreLocalesOptedIn(true)
+        // setting empty locales deletes the persisted locales record.
+        AppLocalesStorageHelper.persistLocales(context, /* empty locales */ "")
+        AppCompatDelegate.setIsAutoStoreLocalesOptedIn(false)
+
+        // clearing locales from framework.
+        // setting the app to follow system.
+        AppCompatDelegate.Api33Impl.localeManagerSetApplicationLocales(
+            AppCompatDelegate.getLocaleManagerForApplication(),
+            LocaleList.getEmptyLocaleList()
+        )
+
+        // disabling component enabled setting for app_locales sync marker.
+        context.packageManager.setComponentEnabledSetting(
+            appLocalesComponent,
+            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+            /* flags= */ PackageManager.DONT_KILL_APP
+        )
+    }
+}
\ No newline at end of file
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesUpdateActivity.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesUpdateActivity.java
new file mode 100644
index 0000000..7678876
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesUpdateActivity.java
@@ -0,0 +1,217 @@
+/*
+ * 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.
+ * 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.appcompat.app;
+
+import static androidx.appcompat.app.LocaleOverlayHelper.combineLocalesIfOverlayExists;
+
+import android.content.res.Configuration;
+import android.os.Build;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.test.R;
+import androidx.appcompat.testutils.BaseTestActivity;
+import androidx.core.os.LocaleListCompat;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+public class LocalesUpdateActivity extends BaseTestActivity {
+
+
+    public static final String KEY_TITLE = "title";
+
+    private final Semaphore mOnConfigurationChangeSemaphore = new Semaphore(0);
+    private final Semaphore mOnDestroySemaphore = new Semaphore(0);
+    private final Semaphore mOnCreateSemaphore = new Semaphore(0);
+
+    private LocaleListCompat mLastLocales = LocaleListCompat.getEmptyLocaleList();
+
+    private Configuration mEffectiveConfiguration;
+    private Configuration mLastConfigurationChange;
+
+    @Override
+    protected int getContentViewLayoutResId() {
+        return R.layout.activity_locales;
+    }
+
+    @Override
+    public void onLocalesChanged(@NonNull LocaleListCompat locales) {
+        mLastLocales = locales;
+    }
+
+    @Override
+    public void onConfigurationChanged(@NonNull Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mLastConfigurationChange = new Configuration(newConfig);
+        mEffectiveConfiguration = mLastConfigurationChange;
+        mOnConfigurationChangeSemaphore.release();
+    }
+
+    @Override
+    public void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+
+        String title = getIntent().getStringExtra(KEY_TITLE);
+        if (title != null) {
+            setTitle(title);
+        }
+
+        mEffectiveConfiguration = new Configuration(getResources().getConfiguration());
+        mOnCreateSemaphore.release();
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+
+        mOnDestroySemaphore.release();
+    }
+
+    @Nullable
+    Configuration getLastConfigurationChangeAndClear() {
+        final Configuration config = mLastConfigurationChange;
+        mLastConfigurationChange = null;
+        return config;
+    }
+
+    /**
+     * @return a copy of the {@link Configuration} from the most recent call to {@link #onCreate} or
+     * {@link #onConfigurationChanged}, or {@code null} if neither has been called yet
+     */
+    @Nullable
+    Configuration getEffectiveConfiguration() {
+        return mEffectiveConfiguration;
+    }
+
+    LocaleListCompat getLastLocalesAndReset() {
+        final LocaleListCompat locales = mLastLocales;
+        mLastLocales = LocaleListCompat.getEmptyLocaleList();
+        return locales;
+    }
+
+    public static LocaleListCompat getConfigLocales(Configuration conf) {
+        if (Build.VERSION.SDK_INT >= 24) {
+            return AppCompatDelegateImpl.Api24Impl.getLocales(conf);
+        } else if (Build.VERSION.SDK_INT >= 21) {
+            return LocaleListCompat.forLanguageTags(AppCompatDelegateImpl.Api21Impl
+                    .toLanguageTag(conf.locale));
+        } else {
+            return LocaleListCompat.create(conf.locale);
+        }
+    }
+
+    public static LocaleListCompat overlayCustomAndSystemLocales(LocaleListCompat customLocales,
+            LocaleListCompat baseLocales) {
+        if (Build.VERSION.SDK_INT >= 24) {
+            return combineLocalesIfOverlayExists(customLocales, baseLocales);
+        } else {
+            return LocaleListCompat.create(customLocales.get(0));
+        }
+    }
+
+    /**
+     * Resets the number of received configuration changes.
+     * <p>
+     * Call this method before {@link #expectOnConfigurationChange(long)} to ensure only future
+     * configuration changes are counted.
+     */
+    public void resetOnConfigurationChange() {
+        mOnConfigurationChangeSemaphore.drainPermits();
+    }
+
+    /**
+     * Blocks until a single configuration change has been received.
+     * <p>
+     * Configuration changes are sticky; if any configuration changes were received prior to
+     * calling this method and {@link #resetOnConfigurationChange()} has not been called, this
+     * method will return immediately.
+     *
+     * @param timeout maximum amount of time (in ms) to wait for a configuration change
+     * @throws InterruptedException if the lock is interrupted
+     */
+    public void expectOnConfigurationChange(long timeout) throws InterruptedException {
+        if (Thread.currentThread() == getMainLooper().getThread()) {
+            throw new IllegalStateException("Method cannot be called on the Activity's UI thread");
+        }
+
+        mOnConfigurationChangeSemaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * Resets the number of received onCreate lifecycle events.
+     * <p>
+     * Call this method before {@link #expectOnCreate(long)} to ensure only future
+     * onCreate lifecycle events are counted.
+     */
+    public void resetOnCreate() {
+        mOnCreateSemaphore.drainPermits();
+    }
+
+    /**
+     * Blocks until a single onCreate lifecycle event has been received.
+     * <p>
+     * Lifecycle events are sticky; if any events were received prior to calling this method and
+     * an event has been received, this method will return immediately.
+     *
+     * @param timeout maximum amount of time (in ms) to wait for an onCreate event
+     * @throws InterruptedException if the lock is interrupted
+     */
+    public void expectOnCreate(long timeout) throws InterruptedException {
+        if (Thread.currentThread() == getMainLooper().getThread()) {
+            throw new IllegalStateException("Method cannot be called on the Activity's UI thread");
+        }
+
+        mOnCreateSemaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * Resets the number of received onDestroy lifecycle events.
+     * <p>
+     * Call this method before {@link #expectOnDestroy(long)} to ensure only future
+     * onDestroy lifecycle events are counted.
+     */
+    public void resetOnDestroy() {
+        mOnDestroySemaphore.drainPermits();
+    }
+
+    /**
+     * Blocks until a single onDestroy lifecycle event has been received.
+     * <p>
+     * Lifecycle events are sticky; if any events were received prior to calling this method and
+     * an event has been received, this method will return immediately.
+     *
+     * @param timeout maximum amount of time (in ms) to wait for an onDestroy event
+     * @throws InterruptedException if the lock is interrupted
+     */
+    public void expectOnDestroy(long timeout) throws InterruptedException {
+        if (Thread.currentThread() == getMainLooper().getThread()) {
+            throw new IllegalStateException("Method cannot be called on the Activity's UI thread");
+        }
+
+        mOnDestroySemaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * Teardown method to clean up persistent locales in static storage.
+     */
+    public static void teardown() {
+        AppCompatDelegate.resetStaticRequestedAndStoredLocales();
+    }
+
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesUpdateTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesUpdateTestCase.kt
new file mode 100644
index 0000000..d504dc6
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesUpdateTestCase.kt
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 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.
+ * 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.appcompat.app
+
+import android.webkit.WebView
+import androidx.appcompat.testutils.LocalesActivityTestRule
+import androidx.appcompat.testutils.LocalesUtils
+import androidx.appcompat.testutils.LocalesUtils.CUSTOM_LOCALE_LIST
+import androidx.appcompat.testutils.LocalesUtils.assertConfigurationLocalesEquals
+import androidx.appcompat.testutils.LocalesUtils.setLocalesAndWait
+import androidx.appcompat.testutils.LocalesUtils.setLocalesAndWaitForRecreate
+import androidx.core.os.LocaleListCompat
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import androidx.testutils.waitForExecution
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNull
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+@LargeTest
+// TODO(b/218430372): Modify SdkSuppress annotation in tests for backward compatibility of
+//  setApplicationLocales
+@SdkSuppress(maxSdkVersion = 31)
+class LocalesUpdateTestCase() {
+    @get:Rule
+    val rule = LocalesActivityTestRule(LocalesUpdateActivity::class.java)
+    var systemLocales = LocaleListCompat.getEmptyLocaleList()
+    var expectedLocales = LocaleListCompat.getEmptyLocaleList()
+
+    @Before
+    fun setUp() {
+        // Since no locales are applied as of now, current configuration will have system
+        // locales.
+        systemLocales = LocalesUpdateActivity.getConfigLocales(rule.activity
+            .resources.configuration)
+        expectedLocales = LocalesUpdateActivity.overlayCustomAndSystemLocales(CUSTOM_LOCALE_LIST,
+            systemLocales)
+    }
+    @Test
+    fun testDialogDoesNotOverrideActivityConfiguration() {
+        setLocalesAndWaitForRecreate(rule, CUSTOM_LOCALE_LIST)
+        // Now show a AppCompatDialog
+        lateinit var dialog: AppCompatDialog
+        rule.runOnUiThread {
+            dialog = AppCompatDialog(rule.activity)
+            dialog.show()
+        }
+        rule.waitForExecution()
+        // Now dismiss the dialog
+        rule.runOnUiThread { dialog.dismiss() }
+
+        // Assert that the locales are unchanged
+        assertConfigurationLocalesEquals(
+            expectedLocales,
+            rule.activity.resources.configuration
+        )
+    }
+
+    @Test
+    fun testLoadingWebViewMaintainsConfiguration() {
+        setLocalesAndWaitForRecreate(rule, CUSTOM_LOCALE_LIST)
+
+        // Now load a WebView into the Activity
+        rule.runOnUiThread { WebView(rule.activity) }
+
+        // Now assert that the context still has applied locales.
+        assertEquals(
+            expectedLocales,
+            LocalesUpdateActivity.getConfigLocales(rule.activity.resources.configuration)
+        )
+    }
+
+    @Test
+    fun testOnLocalesChangedCalled() {
+        val activity = rule.activity
+        // Set local night mode to YES
+        setLocalesAndWait(rule, CUSTOM_LOCALE_LIST)
+        // Assert that the Activity received a new value
+        assertEquals(expectedLocales, activity.lastLocalesAndReset)
+    }
+
+    @Test
+    fun testOnConfigurationChangeNotCalled() {
+        var activity = rule.activity
+        // Set locales to CUSTOM_LOCALE_LIST.
+        LocalesUtils.setLocalesAndWait(
+            rule,
+            CUSTOM_LOCALE_LIST
+        )
+        // Assert that onConfigurationChange was not called on the original activity
+        assertNull(activity.lastConfigurationChangeAndClear)
+
+        activity = rule.activity
+        // Set locales back to system locales.
+        setLocalesAndWait(
+            rule,
+            LocaleListCompat.getEmptyLocaleList()
+        )
+        // Assert that onConfigurationChange was not called
+        assertNull(activity.lastConfigurationChangeAndClear)
+    }
+}
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeForegroundDialogTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeForegroundDialogTestCase.kt
index 2ccfc39..a0e190b 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeForegroundDialogTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeForegroundDialogTestCase.kt
@@ -44,7 +44,7 @@
 
         // Open a dialog on top of the activity.
         rule.runOnUiThread {
-            val frag = NightModeDialogFragment.newInstance()
+            val frag = TestDialogFragment.newInstance()
             frag.show(firstActivity.supportFragmentManager, "dialog")
         }
 
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeDialogFragment.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/TestDialogFragment.java
similarity index 70%
rename from appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeDialogFragment.java
rename to appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/TestDialogFragment.java
index ba3932e..907c068 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeDialogFragment.java
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/TestDialogFragment.java
@@ -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.
@@ -23,22 +23,26 @@
 import androidx.annotation.Nullable;
 import androidx.fragment.app.DialogFragment;
 
-public class NightModeDialogFragment extends DialogFragment {
+/**
+ * Test class extending DialogFragment used for testing of configuration changes like nightMode and
+ * locales.
+ */
+public class TestDialogFragment extends DialogFragment {
 
-    public NightModeDialogFragment() {
+    public TestDialogFragment() {
         // Public empty constructor used to handle lifecycle events.
     }
 
-    public static NightModeDialogFragment newInstance() {
-        return new NightModeDialogFragment();
+    public static TestDialogFragment newInstance() {
+        return new TestDialogFragment();
     }
 
     @NonNull
     @Override
     public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
         AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
-        builder.setTitle("NightModeDialogFragment");
-        builder.setMessage("NightModeDialogFragment");
+        builder.setTitle("TestDialogFragment");
+        builder.setMessage("TestDialogFragment");
         return builder.create();
     }
 }
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/testutils/LocalesActivityTestRule.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/testutils/LocalesActivityTestRule.kt
new file mode 100644
index 0000000..976fac7
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/testutils/LocalesActivityTestRule.kt
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ * 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.appcompat.testutils
+
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatDelegate
+import androidx.appcompat.app.LocalesUpdateActivity
+import androidx.appcompat.testutils.LocalesUtils.initCustomLocaleList
+import androidx.core.os.LocaleListCompat
+
+@Suppress("DEPRECATION")
+class LocalesActivityTestRule<T : AppCompatActivity>(
+    activityClazz: Class<T>,
+    initialTouchMode: Boolean = false,
+    launchActivity: Boolean = true
+) : androidx.test.rule.ActivityTestRule<T>(activityClazz, initialTouchMode, launchActivity) {
+    override fun beforeActivityLaunched() {
+        initCustomLocaleList()
+        // By default we'll set the locales to match system locales, which allows us to make better
+        // assumptions in the test below.
+        runOnUiThread {
+            AppCompatDelegate.setApplicationLocales(LocaleListCompat.getEmptyLocaleList())
+        }
+    }
+
+    override fun afterActivityFinished() {
+        // Reset locales persisted in static storage.
+        LocalesUpdateActivity.teardown()
+    }
+}
\ No newline at end of file
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/testutils/LocalesUtils.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/testutils/LocalesUtils.kt
new file mode 100644
index 0000000..36dd7ea
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/testutils/LocalesUtils.kt
@@ -0,0 +1,165 @@
+/*
+ * 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.
+ * 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.appcompat.testutils
+
+import android.content.Context
+import android.content.res.Configuration
+import android.os.Build
+import android.util.Log
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.app.AppCompatDelegate
+import androidx.core.os.LocaleListCompat
+import androidx.lifecycle.Lifecycle
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.testutils.LifecycleOwnerUtils
+import androidx.testutils.PollingCheck
+import java.util.Locale
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotEquals
+
+object LocalesUtils {
+    private const val LOG_TAG = "LocalesUtils"
+
+    /**
+     * A test {@link LocaleListCompat} containing locales [CANADA_FRENCH, CHINESE].
+     */
+    var CUSTOM_LOCALE_LIST: LocaleListCompat = LocaleListCompat.getEmptyLocaleList()
+
+    fun initCustomLocaleList() {
+        if (Build.VERSION.SDK_INT >= 24) {
+            CUSTOM_LOCALE_LIST = LocaleListCompat.forLanguageTags(
+                Locale.CANADA_FRENCH.toLanguageTag() + "," +
+                    Locale.CHINESE.toLanguageTag()
+            )
+        } else {
+            CUSTOM_LOCALE_LIST = LocaleListCompat.create(Locale.CHINESE)
+        }
+    }
+
+    fun assertConfigurationLocalesEquals(
+        expectedLocales: LocaleListCompat,
+        context: Context
+    ) {
+        assertConfigurationLocalesEquals(
+            null,
+            expectedLocales,
+            context
+        )
+    }
+
+    fun assertConfigurationLocalesEquals(
+        message: String?,
+        expectedLocales: LocaleListCompat,
+        context: Context
+    ) {
+        assertConfigurationLocalesEquals(
+            message,
+            expectedLocales,
+            context.resources.configuration
+        )
+    }
+
+    fun assertConfigurationLocalesEquals(
+        expectedLocales: LocaleListCompat,
+        configuration: Configuration
+    ) {
+        assertConfigurationLocalesEquals(
+            null,
+            expectedLocales,
+            configuration
+        )
+    }
+
+    fun assertConfigurationLocalesEquals(
+        message: String?,
+        expectedLocales: LocaleListCompat,
+        configuration: Configuration
+    ) {
+        if (Build.VERSION.SDK_INT >= 24) {
+            assertEquals(
+                message,
+                expectedLocales.toLanguageTags(),
+                configuration.locales.toLanguageTags()
+            )
+        } else {
+            assertEquals(
+                message,
+                expectedLocales.get(0),
+                @Suppress("DEPRECATION") configuration.locale
+            )
+        }
+    }
+
+    fun <T : AppCompatActivity> setLocalesAndWait(
+        @Suppress("DEPRECATION") activityRule: androidx.test.rule.ActivityTestRule<T>,
+        locales: LocaleListCompat
+    ) {
+        setLocalesAndWait(activityRule.activity, activityRule, locales)
+    }
+
+    fun <T : AppCompatActivity> setLocalesAndWait(
+        activity: AppCompatActivity?,
+        @Suppress("DEPRECATION") activityRule: androidx.test.rule.ActivityTestRule<T>,
+        locales: LocaleListCompat
+    ) {
+        Log.d(
+            LOG_TAG,
+            "setLocalesAndWait on Activity: " + activity +
+                " to locales: " + locales
+        )
+
+        val instrumentation = InstrumentationRegistry.getInstrumentation()
+        activityRule.runOnUiThread { setLocales(locales) }
+        instrumentation.waitForIdleSync()
+    }
+
+    fun <T : AppCompatActivity> setLocalesAndWaitForRecreate(
+        @Suppress("DEPRECATION") activityRule: androidx.test.rule.ActivityTestRule<T>,
+        locales: LocaleListCompat
+    ): T = setLocalesAndWaitForRecreate(activityRule.activity, locales)
+
+    fun <T : AppCompatActivity> setLocalesAndWaitForRecreate(
+        activity: T,
+        locales: LocaleListCompat
+    ): T {
+        Log.d(
+            LOG_TAG,
+            "setLocalesAndWaitForRecreate on Activity: " + activity +
+                " to mode: " + locales
+        )
+
+        LifecycleOwnerUtils.waitUntilState(activity, Lifecycle.State.RESUMED)
+
+        // Screen rotation kicks off a lot of background work, so we might need to wait a bit
+        // between the activity reaching RESUMED state and it actually being shown on screen.
+        PollingCheck.waitFor {
+            activity.hasWindowFocus()
+        }
+        assertNotEquals(locales, getLocales())
+
+        // Now perform locales change and wait for the Activity to be recreated.
+        return LifecycleOwnerUtils.waitForRecreation(activity) {
+            setLocales(locales)
+        }
+    }
+
+    fun setLocales(
+        locales: LocaleListCompat
+    ) = AppCompatDelegate.setApplicationLocales(locales)
+
+    private fun getLocales(): LocaleListCompat = AppCompatDelegate.getApplicationLocales()
+}
\ No newline at end of file
diff --git a/appcompat/appcompat/src/androidTest/res/layout/activity_locales.xml b/appcompat/appcompat/src/androidTest/res/layout/activity_locales.xml
new file mode 100644
index 0000000..cbbdf80
--- /dev/null
+++ b/appcompat/appcompat/src/androidTest/res/layout/activity_locales.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  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.
+  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.
+  -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/text_locales"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="locales" />
+
+    <WebView
+        android:id="@+id/webView"
+        android:layout_width="match_parent"
+        android:layout_height="100dp"
+        android:layout_gravity="bottom" />
+
+</LinearLayout>
\ No newline at end of file
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 981c192..41c34c9 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatActivity.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatActivity.java
@@ -45,6 +45,7 @@
 import androidx.core.app.ActivityCompat;
 import androidx.core.app.NavUtils;
 import androidx.core.app.TaskStackBuilder;
+import androidx.core.os.LocaleListCompat;
 import androidx.fragment.app.FragmentActivity;
 import androidx.lifecycle.ViewTreeLifecycleOwner;
 import androidx.lifecycle.ViewTreeViewModelStoreOwner;
@@ -662,4 +663,13 @@
      */
     protected void onNightModeChanged(@NightMode int mode) {
     }
+
+    /**
+     * Called when the locales have been changed. See {@link AppCompatDelegate#applyAppLocales()}
+     * for more information.
+     *
+     * @param locales the localeListCompat which has been applied
+     */
+    protected void onLocalesChanged(@NonNull LocaleListCompat locales) {
+    }
 }
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
index fc04398..e5b6eaf 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegate.java
@@ -17,12 +17,22 @@
 package androidx.appcompat.app;
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
+import static androidx.appcompat.app.AppLocalesStorageHelper.persistLocales;
+import static androidx.appcompat.app.AppLocalesStorageHelper.readLocales;
+import static androidx.appcompat.app.AppLocalesStorageHelper.syncLocalesToFramework;
+
+import static java.util.Objects.requireNonNull;
 
 import android.app.Activity;
 import android.app.Dialog;
+import android.app.LocaleManager;
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
 import android.content.res.Configuration;
+import android.os.Build;
 import android.os.Bundle;
+import android.os.LocaleList;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.MenuInflater;
@@ -30,7 +40,9 @@
 import android.view.ViewGroup;
 import android.view.Window;
 
+import androidx.annotation.AnyThread;
 import androidx.annotation.CallSuper;
+import androidx.annotation.DoNotInline;
 import androidx.annotation.IdRes;
 import androidx.annotation.IntDef;
 import androidx.annotation.LayoutRes;
@@ -39,10 +51,12 @@
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.StyleRes;
+import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.view.ActionMode;
 import androidx.appcompat.widget.Toolbar;
 import androidx.appcompat.widget.VectorEnabledTintResources;
 import androidx.collection.ArraySet;
+import androidx.core.os.LocaleListCompat;
 import androidx.core.view.WindowCompat;
 import androidx.fragment.app.FragmentActivity;
 
@@ -95,6 +109,10 @@
     static final boolean DEBUG = false;
     static final String TAG = "AppCompatDelegate";
 
+    static AppLocalesStorageHelper.SerialExecutor sSerialExecutorForLocalesStorage = new
+            AppLocalesStorageHelper.SerialExecutor(
+                    new AppLocalesStorageHelper.ThreadPerTaskExecutor());
+
     /**
      * Mode which uses the system's night mode setting to determine if it is night or not.
      *
@@ -165,6 +183,13 @@
     @NightMode
     private static int sDefaultNightMode = MODE_NIGHT_UNSPECIFIED;
 
+    private static LocaleListCompat sRequestedAppLocales = null;
+    private static LocaleListCompat sStoredAppLocales = null;
+    private static Boolean sIsAutoStoreLocalesOptedIn = null;
+    private static boolean sIsFrameworkSyncChecked = false;
+    private static Object sLocaleManager = null;
+    private static Context sAppContext = null;
+
     /**
      * All AppCompatDelegate instances associated with a "live" Activity, e.g. lifecycle state is
      * post-onCreate and pre-onDestroy. These instances are used to instrument night mode's uiMode
@@ -173,6 +198,7 @@
     private static final ArraySet<WeakReference<AppCompatDelegate>> sActivityDelegates =
             new ArraySet<>();
     private static final Object sActivityDelegatesLock = new Object();
+    private static final Object sAppLocalesStorageSyncLock = new Object();
 
     /** @hide */
     @SuppressWarnings("deprecation")
@@ -521,6 +547,31 @@
     public abstract boolean applyDayNight();
 
     /**
+     * Applies the current locales to this delegate's host component.
+     *
+     * <p>Apps can be notified when the locales are changed by overriding the
+     * {@link AppCompatActivity#onLocalesChanged(LocaleListCompat)} method.</p>
+     *
+     * <p>This is a default implementation and it is overridden atin
+     * {@link AppCompatDelegateImpl#applyAppLocales()} </p>
+     *
+     * @see #setApplicationLocales(LocaleListCompat)
+     *
+     * @return true if requested app-specific locales were applied, false if not.
+     */
+    boolean applyAppLocales() {
+        return false;
+    }
+
+    /**
+     * Returns the context for the current delegate.
+     */
+    @Nullable
+    public Context getContextForDelegate() {
+        return null;
+    }
+
+    /**
      * Override the night mode used for this delegate's host component.
      *
      * <p>When setting a mode to be used across an entire app, the
@@ -595,6 +646,109 @@
     }
 
     /**
+     * Sets the current locales for the calling app.
+     *
+     * <p>If this method is called after any host components with attached
+     * {@link AppCompatDelegate}s have been 'created', a {@link LocaleList} configuration
+     * change will occur in each. This may result in those components being recreated, depending
+     * on their manifest configuration.</p>
+     *
+     * <p>This method accepts {@link LocaleListCompat} as an input parameter.</p>
+     *
+     * <p>Apps should continue to read Locales via their in-process {@link LocaleList}s.</p>
+     *
+     * <p>On API level 33 and above, this API will handle storage automatically.</p>
+     *
+     * <p>For API levels below that, the developer has two options:</p>
+     * <ul>
+     *     <li>They can opt-in to automatic storage handled through the library. They can do this by
+     *     adding a special metaData entry in their {@code AndroidManifest.xml}, similar to :
+     *     <pre><code>
+     *     &lt;service
+     *         android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
+     *         android:enabled="false"
+     *         android:exported="false"&gt;
+     *         &lt;meta-data
+     *             android:name="autoStoreLocales"
+     *             android:value="true" /&gt;
+     *     &lt;/service&gt;
+     *     </code></pre>
+     *     They should be mindful that this will cause a blocking diskRead and diskWrite
+     *     strictMode violation, and they might need to suppress it at their end.</li>
+     *
+     *     <li>The second option is that they can choose to handle storage themselves. In order to
+     *     do so they must use this API to initialize locales during app-start up and provide
+     *     their stored locales. In this case, API should be called before Activity.onCreate()
+     *     in the activity lifecycle, e.g. in attachBaseContext().
+     *     <b>Note: Developers should gate this to API versions < 33.</b></li>
+     * </ul>
+     *
+     * <p>When the application using this API with API versions < 33 updates to a
+     * version >= 33, then there can be two scenarios for this transition:
+     * <ul>
+     *     <li>If the developer has opted-in for autoStorage then the locales will be automatically
+     *     synced to the framework. Developers must specify android:enabled="false" for the
+     *     AppLocalesMetadataHolderService as shown in the meta-data entry above.</li>
+     *     <li>If the developer has not opted-in for autoStorage then they will need to handle
+     *     this transition on their end.</li>
+     * </ul>
+     *
+     * @param locales a list of locales.
+     */
+    public static void setApplicationLocales(@NonNull LocaleListCompat locales) {
+        requireNonNull(locales);
+        if (Build.VERSION.SDK_INT >= 33) {
+            // If the API version is 33 (version for T) or above we want to redirect the call to
+            // the framework API.
+            Object localeManager = getLocaleManagerForApplication();
+            if (localeManager != null) {
+                Api33Impl.localeManagerSetApplicationLocales(localeManager,
+                        Api24Impl.localeListForLanguageTags(locales.toLanguageTags()));
+            }
+        } else {
+            if (DEBUG) {
+                Log.d(TAG, String.format("sRequestedAppLocales. New:%s, Current:%s",
+                        locales, sRequestedAppLocales));
+            }
+            if (!locales.equals(sRequestedAppLocales)) {
+                synchronized (sActivityDelegatesLock) {
+                    sRequestedAppLocales = locales;
+                    applyLocalesToActiveDelegates();
+                }
+            } else if (DEBUG) {
+                Log.d(TAG, String.format("Not applying changes, sRequestedAppLocales is already %s",
+                        locales));
+            }
+        }
+    }
+
+    /**
+     * Returns application locales for the calling app as a {@link LocaleListCompat}.
+     *
+     * <p>Returns a {@link LocaleListCompat#getEmptyLocaleList()} if no app-specific locales are
+     * set.
+     */
+    @AnyThread
+    @NonNull
+    public static LocaleListCompat getApplicationLocales() {
+        if (Build.VERSION.SDK_INT >= 33) {
+            // If the API version is 33 or above we want to redirect the call to the framework API.
+            Object localeManager = getLocaleManagerForApplication();
+            if (localeManager != null) {
+                return LocaleListCompat.wrap(Api33Impl.localeManagerGetApplicationLocales(
+                        localeManager));
+            }
+        } else {
+            if (sRequestedAppLocales != null) {
+                // If app-specific locales exists then sRequestedApplicationLocales contains the
+                // latest locales.
+                return sRequestedAppLocales;
+            }
+        }
+        return LocaleListCompat.getEmptyLocaleList();
+    }
+
+    /**
      * Returns the default night mode.
      *
      * @see #setDefaultNightMode(int)
@@ -605,6 +759,182 @@
     }
 
     /**
+     * Returns the requested app locales.
+     *
+     * @see #setApplicationLocales(LocaleListCompat)
+     */
+    @Nullable
+    static LocaleListCompat getRequestedAppLocales() {
+        return sRequestedAppLocales;
+    }
+
+    /**
+     * Returns the stored app locales.
+     *
+     * @see #setApplicationLocales(LocaleListCompat)
+     */
+    @Nullable
+    static LocaleListCompat getStoredAppLocales() {
+        return sStoredAppLocales;
+    }
+
+    /**
+     * Resets the static variables for requested and stored locales to null. This method is used
+     * for testing as it mimics activity restart which is difficult to do in a test.
+     */
+    @VisibleForTesting
+    static void resetStaticRequestedAndStoredLocales() {
+        sRequestedAppLocales = null;
+        sStoredAppLocales = null;
+    }
+
+    /**
+     * Sets {@link AppCompatDelegate#sIsAutoStoreLocalesOptedIn} to the provided value. This method
+     * is used for testing, setting sIsAutoStoreLocalesOptedIn to true mimics adding an opt-in
+     * "autoStoreLocales" meta-data entry.
+     *
+     * see {@link AppCompatDelegate#setApplicationLocales(LocaleListCompat)}.
+     */
+    @VisibleForTesting
+    static void setIsAutoStoreLocalesOptedIn(boolean isAutoStoreLocalesOptedIn) {
+        sIsAutoStoreLocalesOptedIn = isAutoStoreLocalesOptedIn;
+    }
+
+    /**
+     * Returns the localeManager for the current application using active delegates to fetch
+     * context, returns null if no active delegates present.
+     */
+    @RequiresApi(33)
+    static Object getLocaleManagerForApplication() {
+        if (sLocaleManager != null) {
+            return sLocaleManager;
+        }
+        // Traversing through the active delegates to retrieve context for any one non null
+        // delegate.
+        // This context is used to create a localeManager which is saved as a static variable to
+        // reduce multiple object creation for different activities.
+        if (sAppContext == null) {
+            for (WeakReference<AppCompatDelegate> activeDelegate : sActivityDelegates) {
+                final AppCompatDelegate delegate = activeDelegate.get();
+                if (delegate != null) {
+                    Context context = delegate.getContextForDelegate();
+                    if (context != null) {
+                        sAppContext = context;
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (sAppContext != null) {
+            sLocaleManager = sAppContext.getSystemService(Context.LOCALE_SERVICE);
+        }
+        return sLocaleManager;
+    }
+
+    /**
+     * Returns true is the "autoStoreLocales" metaData is marked true in the app manifest.
+     */
+    static boolean isAutoStorageOptedIn(Context context) {
+        if (sIsAutoStoreLocalesOptedIn == null) {
+            try {
+                ServiceInfo serviceInfo = AppLocalesMetadataHolderService.getServiceInfo(
+                        context);
+                if (serviceInfo.metaData != null) {
+                    sIsAutoStoreLocalesOptedIn = serviceInfo.metaData.getBoolean(
+                            /* key= */ "autoStoreLocales");
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.d(TAG, "Checking for metadata for AppLocalesMetadataHolderService "
+                        + ": Service not found");
+                sIsAutoStoreLocalesOptedIn = false;
+            }
+        }
+        return sIsAutoStoreLocalesOptedIn;
+    }
+
+    /**
+     * Executes {@link AppCompatDelegate#syncRequestedAndStoredLocales(Context)} asynchronously
+     * on a worker thread, serialized using {@link
+     * AppCompatDelegate#sSerialExecutorForLocalesStorage}.
+     *
+     * <p>This is done to perform the storage read operation without blocking the main thread.</p>
+     */
+    void asyncExecuteSyncRequestedAndStoredLocales(Context context) {
+        sSerialExecutorForLocalesStorage.execute(() -> syncRequestedAndStoredLocales(context));
+    }
+
+    /**
+     * Syncs requested and persisted app-specific locales.
+     *
+     * <p>This sync is only performed if the developer has opted in to use the autoStoredLocales
+     * feature, marked by the metaData "autoStoreLocales" wrapped in the service
+     * "AppLocalesMetadataHolderService". If the metaData is not found in the manifest or holds
+     * the value false then we return from this function without doing anything. If the metaData
+     * is set to true, then we perform a sync for app-locales.</p>
+     *
+     * <p>If the API version is >=33, then the storage is checked for app-specific locales, if
+     * found they are synced to the framework by calling the
+     * {@link AppCompatDelegate#setApplicationLocales(LocaleListCompat)}</p>
+     *
+     * <p>If the API version is <33, then there are two scenarios:</p>
+     * <ul>
+     * <li>If the requestedAppLocales are not set then the app-specific locales are read from
+     * storage. If persisted app-specific locales are found then they are used to
+     * update the requestedAppLocales.</li>
+     * <li>If the requestedAppLocales are populated and are different from the stored locales
+     * then in that case the requestedAppLocales are stored and the static variable for
+     * storedAppLocales is updated accordingly.</li>
+     * </ul>
+     */
+    static void syncRequestedAndStoredLocales(Context context) {
+        if (!isAutoStorageOptedIn(context)) {
+            return;
+        } else if (Build.VERSION.SDK_INT >= 33) {
+            // TODO: After BuildCompat.isAtLeast() is deprecated, the above condition needs to be
+            //  replaced by (Build.VERSION.SDK_INT == 33).
+            if (!sIsFrameworkSyncChecked) {
+                // syncs locales from androidX to framework, it only happens once after the
+                // device is updated to T (API version 33).
+                sSerialExecutorForLocalesStorage.execute(() -> {
+                    syncLocalesToFramework(context);
+                    sIsFrameworkSyncChecked = true;
+                });
+            }
+        } else {
+            synchronized (sAppLocalesStorageSyncLock) {
+                if (sRequestedAppLocales == null) {
+                    if (sStoredAppLocales == null) {
+                        sStoredAppLocales =
+                                LocaleListCompat.forLanguageTags(readLocales(context));
+                    }
+                    if (sStoredAppLocales.isEmpty()) {
+                        // if both requestedLocales and storedLocales not set, then the user has not
+                        // specified any application-specific locales. So no alterations in current
+                        // application locales should take place.
+                        return;
+                    }
+                    sRequestedAppLocales = sStoredAppLocales;
+                } else if (!sRequestedAppLocales.equals(sStoredAppLocales)) {
+                    // if requestedLocales is set and is not equal to the storedLocales then in this
+                    // case we need to store these locales in storage.
+                    sStoredAppLocales = sRequestedAppLocales;
+                    persistLocales(context, sRequestedAppLocales.toLanguageTags());
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Sets the value for {@link AppCompatDelegate#sAppContext} which is the context for the
+     * current application.
+     */
+    static void setAppContext(Context context) {
+        sAppContext = context;
+    }
+
+    /**
      * Sets whether vector drawables on older platforms (< API 21) can be used within
      * {@link android.graphics.drawable.DrawableContainer} resources.
      *
@@ -695,4 +1025,48 @@
             }
         }
     }
+
+    private static void applyLocalesToActiveDelegates() {
+        for (WeakReference<AppCompatDelegate> activeDelegate : sActivityDelegates) {
+            final AppCompatDelegate delegate = activeDelegate.get();
+            if (delegate != null) {
+                if (DEBUG) {
+                    Log.d(TAG, "applyLocalesToActiveDelegates. Applying to " + delegate);
+                }
+                delegate.applyAppLocales();
+            }
+        }
+    }
+
+    @RequiresApi(24)
+    static class Api24Impl {
+        private Api24Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static LocaleList localeListForLanguageTags(String list) {
+            return LocaleList.forLanguageTags(list);
+        }
+    }
+
+    @RequiresApi(33)
+    static class Api33Impl {
+        private Api33Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static void localeManagerSetApplicationLocales(Object localeManager,
+                LocaleList locales) {
+            LocaleManager mLocaleManager = (LocaleManager) localeManager;
+            mLocaleManager.setApplicationLocales(locales);
+        }
+
+        @DoNotInline
+        static LocaleList localeManagerGetApplicationLocales(Object localeManager) {
+            LocaleManager mLocaleManager = (LocaleManager) localeManager;
+            return mLocaleManager.getApplicationLocales();
+        }
+    }
 }
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
index 3cd8711..e4f5f19 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
@@ -24,6 +24,7 @@
 import static android.view.Window.FEATURE_OPTIONS_PANEL;
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+import static androidx.appcompat.app.LocaleOverlayHelper.combineLocalesIfOverlayExists;
 
 import android.annotation.SuppressLint;
 import android.app.Activity;
@@ -75,6 +76,7 @@
 import android.widget.TextView;
 
 import androidx.annotation.CallSuper;
+import androidx.annotation.DoNotInline;
 import androidx.annotation.IdRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -109,6 +111,7 @@
 import androidx.core.app.NavUtils;
 import androidx.core.content.ContextCompat;
 import androidx.core.content.res.ResourcesCompat;
+import androidx.core.os.LocaleListCompat;
 import androidx.core.util.ObjectsCompat;
 import androidx.core.view.KeyEventDispatcher;
 import androidx.core.view.LayoutInflaterCompat;
@@ -125,6 +128,7 @@
 import org.xmlpull.v1.XmlPullParser;
 
 import java.util.List;
+import java.util.Locale;
 
 /**
  * @hide
@@ -258,9 +262,8 @@
     private int mLocalNightMode = MODE_NIGHT_UNSPECIFIED;
 
     private int mThemeResId;
-    private boolean mActivityHandlesUiMode;
-    private boolean mActivityHandlesUiModeChecked;
-
+    private int mActivityHandlesConfigFlags;
+    private boolean mActivityHandlesConfigFlagsChecked;
     private AutoNightModeManager mAutoTimeNightModeManager;
     private AutoNightModeManager mAutoBatteryNightModeManager;
 
@@ -360,13 +363,22 @@
 
         final int modeToApply = mapNightMode(baseContext, calculateNightMode());
 
+        if (isAutoStorageOptedIn(baseContext)) {
+            // If the developer has opted in to auto store the locales, then we use
+            // syncRequestedAndStoredLocales() to load the saved locales from storage. This is
+            // performed only during cold app start-ups because in other cases the locales can be
+            // found in the static storage.
+            syncRequestedAndStoredLocales(baseContext);
+        }
+        final LocaleListCompat localesToApply = calculateApplicationLocales(baseContext);
+
         // If the base context is a ContextThemeWrapper (thus not an Application context)
         // and nobody's touched its Resources yet, we can shortcut and directly apply our
         // override configuration.
         if (sCanApplyOverrideConfiguration
                 && baseContext instanceof android.view.ContextThemeWrapper) {
-            final Configuration config = createOverrideConfigurationForDayNight(
-                    baseContext, modeToApply, null, false);
+            final Configuration config = createOverrideAppConfiguration(
+                    baseContext, modeToApply, localesToApply, null, false);
             if (DEBUG) {
                 Log.d(TAG, String.format("Attempting to apply config to base context: %s",
                         config.toString()));
@@ -385,8 +397,8 @@
 
         // Again, but using the AppCompat version of ContextThemeWrapper.
         if (baseContext instanceof ContextThemeWrapper) {
-            final Configuration config = createOverrideConfigurationForDayNight(
-                    baseContext, modeToApply, null, false);
+            final Configuration config = createOverrideAppConfiguration(
+                    baseContext, modeToApply, localesToApply, null, false);
             if (DEBUG) {
                 Log.d(TAG, String.format("Attempting to apply config to base context: %s",
                         config.toString()));
@@ -442,8 +454,8 @@
             }
         }
 
-        final Configuration config = createOverrideConfigurationForDayNight(
-                baseContext, modeToApply, configOverlay, true);
+        final Configuration config = createOverrideAppConfiguration(
+                baseContext, modeToApply, localesToApply, configOverlay, true);
         if (DEBUG) {
             Log.d(TAG, String.format("Applying night mode using ContextThemeWrapper and "
                     + "applyOverrideConfiguration(). Config: %s", config.toString()));
@@ -452,7 +464,8 @@
         // Next, we'll wrap the base context to ensure any method overrides or themes are left
         // intact. Since ThemeOverlay.AppCompat theme is empty, we'll get the base context's theme.
         final ContextThemeWrapper wrappedContext = new ContextThemeWrapper(baseContext,
-                R.style.Theme_AppCompat_Empty, isActivityManifestHandlingUiMode(baseContext));
+                R.style.Theme_AppCompat_Empty,
+                getActivityHandlesConfigChangesFlags(baseContext) != 0);
         wrappedContext.applyOverrideConfiguration(config);
 
         // Check whether the base context has an explicit theme or is able to obtain one
@@ -497,9 +510,9 @@
         // Dialogs, etc
         mBaseContextAttached = true;
 
-        // Our implicit call to applyDayNight() should not recreate until after the Activity is
-        // created
-        applyDayNight(false);
+        // Our implicit call to applyApplicationSpecificConfig() should not recreate
+        // until after the Activity is created
+        applyApplicationSpecificConfig(false);
 
         // We lazily fetch the Window for Activities, to allow DayNight to apply in
         // attachBaseContext
@@ -661,16 +674,18 @@
         // inspects the last-seen configuration. Otherwise, we'll recurse back to this method.
         mEffectiveConfiguration = new Configuration(mContext.getResources().getConfiguration());
 
-        // Re-apply Day/Night with the new configuration but disable recreations. Since this
-        // configuration change has only just happened we can safely just update the resources now
-        applyDayNight(false);
+        // Re-apply Day/Night and locales with the new configuration but disable recreations.
+        // Since this configuration change has only just happened we can safely just update the
+        // resources now.
+        applyApplicationSpecificConfig(false);
     }
 
     @Override
     public void onStart() {
         // This will apply day/night if the time has changed, it will also call through to
-        // setupAutoNightModeIfNeeded()
-        applyDayNight();
+        // setupAutoNightModeIfNeeded(). Also, this will make sure that the latest
+        // app-specific locales are applied and activity is recreated if needed.
+        applyApplicationSpecificConfig(true);
     }
 
     @Override
@@ -2369,15 +2384,35 @@
     }
 
     @Override
+    public Context getContextForDelegate() {
+        return mContext;
+    }
+
+    @Override
     public boolean applyDayNight() {
-        return applyDayNight(true);
+        return applyApplicationSpecificConfig(true);
+    }
+
+    @Override
+    boolean applyAppLocales() {
+        // This method is only reached when there is an explicit call to setApplicationLocales().
+        if (isAutoStorageOptedIn(mContext)
+                && getRequestedAppLocales() != null
+                && !getRequestedAppLocales().equals(getStoredAppLocales())) {
+            // If the developer has opted in to autoStore the locales, we need to store the locales
+            // for the application here. This is done using the syncRequestedAndStoredLocales,
+            // called asynchronously on a worker thread.
+            asyncExecuteSyncRequestedAndStoredLocales(mContext);
+        }
+        return applyApplicationSpecificConfig(true);
     }
 
     @SuppressWarnings("deprecation")
-    private boolean applyDayNight(final boolean allowRecreation) {
+    private boolean applyApplicationSpecificConfig(final boolean allowRecreation) {
         if (mDestroyed) {
             if (DEBUG) {
-                Log.d(TAG, "applyDayNight. Skipping because host is destroyed");
+                Log.d(TAG, "applyApplicationSpecificConfig. Skipping because host is "
+                        + "destroyed");
             }
             // If we're destroyed, ignore the call
             return false;
@@ -2385,7 +2420,14 @@
 
         @NightMode final int nightMode = calculateNightMode();
         @ApplyableNightMode final int modeToApply = mapNightMode(mContext, nightMode);
-        final boolean applied = updateForNightMode(modeToApply, allowRecreation);
+
+        LocaleListCompat localesToBeApplied = null;
+        if (Build.VERSION.SDK_INT < 33) {
+            localesToBeApplied = calculateApplicationLocales(mContext);
+        }
+
+        final boolean applied = updateAppConfiguration(modeToApply, localesToBeApplied,
+                allowRecreation);
 
         if (nightMode == MODE_NIGHT_AUTO_TIME) {
             getAutoTimeNightModeManager(mContext).setup();
@@ -2403,6 +2445,50 @@
         return applied;
     }
 
+    /**
+     * Returns the required {@link LocaleListCompat}  for the current application. This method
+     * checks for requested app-specific locales and returns them after an overlay
+     * with the system locales. If requested app-specific do not exist, it returns a null.
+     */
+    @Nullable
+    LocaleListCompat calculateApplicationLocales(@NonNull Context context) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return null;
+        }
+        LocaleListCompat requestedLocales = getRequestedAppLocales();
+        if (requestedLocales == null) {
+            return null;
+        }
+        LocaleListCompat systemLocales = getConfigurationLocales(
+                context.getApplicationContext()
+                        .getResources().getConfiguration());
+
+        LocaleListCompat localesToBeApplied;
+        if (Build.VERSION.SDK_INT >= 24) {
+            // For API>=24 the application locales are applied as a localeList. The localeList
+            // to be applied is an overlay of app-specific locales and the system locales.
+            localesToBeApplied = combineLocalesIfOverlayExists(requestedLocales,
+                    systemLocales);
+        } else {
+            // For API<24 the application does not have a localeList instead it has a single
+            // locale, which we have set as the locale with the highest preference i.e. the first
+            // one from the requested locales.
+            if (requestedLocales.isEmpty()) {
+                localesToBeApplied = LocaleListCompat.getEmptyLocaleList();
+            } else {
+                localesToBeApplied =
+                        LocaleListCompat.forLanguageTags(requestedLocales.get(0).toString());
+            }
+        }
+
+        if (localesToBeApplied.isEmpty()) {
+            // If the localesToBeApplied is empty, it implies that there are no app-specific locales
+            // set for this application and systemLocales should be followed.
+            localesToBeApplied = systemLocales;
+        }
+        return localesToBeApplied;
+    }
+
     @Override
     @RequiresApi(17)
     public void setLocalNightMode(@NightMode int mode) {
@@ -2461,9 +2547,38 @@
         return mLocalNightMode != MODE_NIGHT_UNSPECIFIED ? mLocalNightMode : getDefaultNightMode();
     }
 
+    void setConfigurationLocales(Configuration conf, @NonNull LocaleListCompat locales) {
+        if (Build.VERSION.SDK_INT >= 24) {
+            Api24Impl.setLocales(conf, locales);
+        } else if (Build.VERSION.SDK_INT >= 17) {
+            Api17Impl.setLocale(conf, locales.get(0));
+            Api17Impl.setLayoutDirection(conf, locales.get(0));
+        } else {
+            conf.locale = locales.get(0);
+        }
+    }
+
+    LocaleListCompat getConfigurationLocales(Configuration conf) {
+        if (Build.VERSION.SDK_INT >= 24) {
+            return Api24Impl.getLocales(conf);
+        } else if (Build.VERSION.SDK_INT >= 21) {
+            return LocaleListCompat.forLanguageTags(Api21Impl.toLanguageTag(conf.locale));
+        } else {
+            return LocaleListCompat.create(conf.locale);
+        }
+    }
+
+    void setDefaultLocalesForLocaleList(LocaleListCompat locales) {
+        if (Build.VERSION.SDK_INT >= 24) {
+            Api24Impl.setDefaultLocales(locales);
+        } else {
+            Locale.setDefault(locales.get(0));
+        }
+    }
+
     @NonNull
-    private Configuration createOverrideConfigurationForDayNight(
-            @NonNull Context context, @ApplyableNightMode final int mode,
+    private Configuration createOverrideAppConfiguration(@NonNull Context context,
+            @ApplyableNightMode int mode, @Nullable LocaleListCompat locales,
             @Nullable Configuration configOverlay, boolean ignoreFollowSystem) {
         int newNightMode;
         switch (mode) {
@@ -2496,43 +2611,76 @@
         overrideConf.uiMode = newNightMode
                 | (overrideConf.uiMode & ~Configuration.UI_MODE_NIGHT_MASK);
 
+        if (locales != null) {
+            setConfigurationLocales(overrideConf, locales);
+        }
         return overrideConf;
     }
 
     /**
-     * Updates the {@link Resources} configuration {@code uiMode} with the
-     * chosen {@code UI_MODE_NIGHT} value.
+     * Updates the {@link Resources} configuration {@code uiMode}  and {@Link LocaleList} with the
+     * chosen configuration values.
      *
-     * @param mode The new night mode to apply
+     * @param nightMode The new night mode to apply
+     * @param locales The new Locales to be applied
      * @param allowRecreation whether to attempt activity recreate
      * @return true if an action has been taken (recreation, resources updating, etc)
      */
-    private boolean updateForNightMode(@ApplyableNightMode final int mode,
-            final boolean allowRecreation) {
+    private boolean updateAppConfiguration(int nightMode, @Nullable LocaleListCompat
+            locales, final boolean allowRecreation) {
         boolean handled = false;
 
         final Configuration overrideConfig =
-                createOverrideConfigurationForDayNight(mContext, mode, null, false);
+                createOverrideAppConfiguration(mContext, nightMode, locales, null, false);
 
-        final boolean activityHandlingUiMode = isActivityManifestHandlingUiMode(mContext);
+        final int activityHandlingConfigChange = getActivityHandlesConfigChangesFlags(mContext);
         final Configuration currentConfiguration = mEffectiveConfiguration == null
                 ? mContext.getResources().getConfiguration() : mEffectiveConfiguration;
         final int currentNightMode = currentConfiguration.uiMode
                 & Configuration.UI_MODE_NIGHT_MASK;
         final int newNightMode = overrideConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;
 
-        if (DEBUG) {
-            Log.d(TAG, String.format(
-                    "updateForNightMode [allowRecreation:%s, currentNightMode:%d, "
-                            + "newNightMode:%d, activityHandlingUiMode:%s, baseContextAttached:%s, "
-                            + "created:%s, canReturnDifferentContext:%s, host:%s]",
-                    allowRecreation, currentNightMode, newNightMode, activityHandlingUiMode,
-                    mBaseContextAttached, mCreated, sCanReturnDifferentContext, mHost));
+        final LocaleListCompat currentLocales = getConfigurationLocales(currentConfiguration);
+        final LocaleListCompat newLocales;
+        if (locales == null) {
+            newLocales = null;
+        } else {
+            newLocales = getConfigurationLocales(overrideConfig);
         }
 
-        if (currentNightMode != newNightMode
+        // Bitmask representing if there is a change in nightMode or Locales, mapped by bits
+        // ActivityInfo.CONFIG_UI_MODE and ActivityInfo.CONFIG_LOCALE respectively.
+        int configChanges = 0;
+        if (currentNightMode != newNightMode) {
+            configChanges |= ActivityInfo.CONFIG_UI_MODE;
+        }
+        if (newLocales != null && !currentLocales.equals(newLocales)) {
+            configChanges |= ActivityInfo.CONFIG_LOCALE;
+            if (Build.VERSION.SDK_INT >= 17) {
+                configChanges |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
+            }
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, String.format(
+                    "updateAppConfiguration [allowRecreation:%s, "
+                            + "currentNightMode:%s, newNightMode:%s, currentLocales:%s, "
+                            + "newLocales:%s, activityHandlingNightModeChanges:%s, "
+                            + "activityHandlingLocalesChanges:%s, "
+                            + "activityHandlingLayoutDirectionChanges:%s, "
+                            + "baseContextAttached:%s, "
+                            + "created:%s, canReturnDifferentContext:%s, host:%s]",
+                    allowRecreation, currentNightMode, newNightMode,
+                    currentLocales,
+                    newLocales,
+                    ((activityHandlingConfigChange & ActivityInfo.CONFIG_UI_MODE) != 0),
+                    ((activityHandlingConfigChange & ActivityInfo.CONFIG_LOCALE) != 0),
+                    ((activityHandlingConfigChange & ActivityInfo.CONFIG_LAYOUT_DIRECTION) != 0),
+                    mBaseContextAttached, mCreated,
+                    sCanReturnDifferentContext, mHost));
+        }
+        if ((~activityHandlingConfigChange & configChanges) != 0
                 && allowRecreation
-                && !activityHandlingUiMode
                 && mBaseContextAttached
                 && (sCanReturnDifferentContext || mCreated)
                 && mHost instanceof Activity
@@ -2541,41 +2689,56 @@
             // attachBaseContext() + createConfigurationContext() code path.
             // Else, we need to use updateConfiguration() before we're 'created' (below)
             if (DEBUG) {
-                Log.d(TAG, "updateForNightMode attempting to recreate Activity: " + mHost);
+                Log.d(TAG, "updateAppConfiguration attempting to recreate Activity: "
+                        + mHost);
             }
             ActivityCompat.recreate((Activity) mHost);
             handled = true;
         } else if (DEBUG) {
-            Log.d(TAG, "updateForNightMode not recreating Activity: " + mHost);
+            Log.d(TAG, "updateAppConfiguration not recreating Activity: " + mHost);
         }
 
-        if (!handled && currentNightMode != newNightMode) {
+        if (!handled && (configChanges != 0)) {
             // Else we need to use the updateConfiguration path
             if (DEBUG) {
-                Log.d(TAG, "updateForNightMode. Updating resources config on host: " + mHost);
+                Log.d(TAG, "updateAppConfiguration. Updating resources config on host: "
+                        + mHost);
             }
-            updateResourcesConfigurationForNightMode(newNightMode, activityHandlingUiMode, null);
+            // If all the configurations that need to be altered are handled by the activity,
+            // only then callOnConfigChange is set to true.
+            updateResourcesConfiguration(newNightMode, newLocales,
+                    /* callOnConfigChange = */(configChanges & activityHandlingConfigChange)
+                            == configChanges, null);
+
             handled = true;
         }
 
         if (DEBUG && !handled) {
-            Log.d(TAG, "updateForNightMode. Skipping. Night mode: " + mode + " for host:" + mHost);
+            Log.d(TAG,
+                    "updateAppConfiguration. Skipping. nightMode: " + nightMode + " and "
+                            + "locales: " +  locales + " for host:" + mHost);
         }
 
-        // Notify the activity of the night mode. We only notify if we handled the change,
-        // or the Activity is set to handle uiMode changes
         if (handled && mHost instanceof AppCompatActivity) {
-            ((AppCompatActivity) mHost).onNightModeChanged(mode);
+            if ((configChanges & ActivityInfo.CONFIG_UI_MODE) != 0) {
+                ((AppCompatActivity) mHost).onNightModeChanged(nightMode);
+            }
+            if ((configChanges & ActivityInfo.CONFIG_LOCALE) != 0) {
+                ((AppCompatActivity) mHost).onLocalesChanged(locales);
+            }
         }
 
+        if (handled && newLocales != null) {
+            setDefaultLocalesForLocaleList(newLocales);
+        }
         return handled;
     }
 
-    private void updateResourcesConfigurationForNightMode(
-            final int uiModeNightModeValue, final boolean callOnConfigChange,
+    private void updateResourcesConfiguration(int uiModeNightModeValue,
+            @Nullable final LocaleListCompat locales, final boolean callOnConfigChange,
             @Nullable Configuration configOverlay) {
-        // If the Activity is not set to handle uiMode config changes we will
-        // update the Resources with a new Configuration with an updated UI Mode
+        // If the Activity is not set to handle config changes we will
+        // update the Resources with a new Configuration with  updated nightMode and locales.
         final Resources res = mContext.getResources();
         final Configuration conf = new Configuration(res.getConfiguration());
         if (configOverlay != null) {
@@ -2583,6 +2746,9 @@
         }
         conf.uiMode = uiModeNightModeValue
                 | (res.getConfiguration().uiMode & ~Configuration.UI_MODE_NIGHT_MASK);
+        if (locales != null) {
+            setConfigurationLocales(conf, locales);
+        }
         res.updateConfiguration(conf, null);
 
         // We may need to flush the Resources' drawable cache due to framework bugs.
@@ -2606,19 +2772,23 @@
         }
 
         if (callOnConfigChange && mHost instanceof Activity) {
-            final Activity activity = (Activity) mHost;
-            if (activity instanceof LifecycleOwner) {
-                // If the Activity is a LifecyleOwner, check that it is after onCreate() and
-                // before onDestroy(), which includes STOPPED.
-                Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
-                if (lifecycle.getCurrentState().isAtLeast(Lifecycle.State.CREATED)) {
-                    activity.onConfigurationChanged(conf);
-                }
-            } else {
-                // Otherwise, we'll fallback to our internal created and destroyed flags.
-                if (mCreated && !mDestroyed) {
-                    activity.onConfigurationChanged(conf);
-                }
+            updateActivityConfiguration(conf);
+        }
+    }
+
+    private void updateActivityConfiguration(Configuration conf) {
+        final Activity activity = (Activity) mHost;
+        if (activity instanceof LifecycleOwner) {
+            // If the Activity is a LifecyleOwner, check that it is after onCreate() and
+            // before onDestroy(), which includes STOPPED.
+            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
+            if (lifecycle.getCurrentState().isAtLeast(Lifecycle.State.CREATED)) {
+                activity.onConfigurationChanged(conf);
+            }
+        } else {
+            // Otherwise, we'll fallback to our internal created and destroyed flags.
+            if (mCreated && !mDestroyed) {
+                activity.onConfigurationChanged(conf);
             }
         }
     }
@@ -2648,13 +2818,14 @@
         return mAutoBatteryNightModeManager;
     }
 
-    private boolean isActivityManifestHandlingUiMode(Context baseContext) {
-        if (!mActivityHandlesUiModeChecked && mHost instanceof Activity) {
+    private int getActivityHandlesConfigChangesFlags(Context baseContext) {
+        if (!mActivityHandlesConfigFlagsChecked
+                && mHost instanceof Activity) {
             final PackageManager pm = baseContext.getPackageManager();
             if (pm == null) {
-                // If we don't have a PackageManager, return false. Don't set
+                // If we don't have a PackageManager, return 0. Don't set
                 // the checked flag though so we still check again later
-                return false;
+                return 0;
             }
             try {
                 int flags = 0;
@@ -2671,19 +2842,19 @@
                 }
                 final ActivityInfo info = pm.getActivityInfo(
                         new ComponentName(baseContext, mHost.getClass()), flags);
-                mActivityHandlesUiMode = info != null
-                        && (info.configChanges & ActivityInfo.CONFIG_UI_MODE) != 0;
+                if (info != null) {
+                    mActivityHandlesConfigFlags = info.configChanges;
+                }
             } catch (PackageManager.NameNotFoundException e) {
                 // This shouldn't happen but let's not crash because of it, we'll just log and
                 // return false (since most apps won't be handling it)
                 Log.d(TAG, "Exception while getting ActivityInfo", e);
-                mActivityHandlesUiMode = false;
+                mActivityHandlesConfigFlags = 0;
             }
         }
         // Flip the checked flag so we don't check again
-        mActivityHandlesUiModeChecked = true;
-
-        return mActivityHandlesUiMode;
+        mActivityHandlesConfigFlagsChecked = true;
+        return mActivityHandlesConfigFlags;
     }
 
     /**
@@ -3607,6 +3778,16 @@
                 @NonNull Configuration overrideConfiguration) {
             return context.createConfigurationContext(overrideConfiguration);
         }
+
+        @DoNotInline
+        static void setLayoutDirection(Configuration configuration, Locale loc) {
+            configuration.setLayoutDirection(loc);
+        }
+
+        @DoNotInline
+        static void setLocale(Configuration configuration, Locale loc) {
+            configuration.setLocale(loc);
+        }
     }
 
     @RequiresApi(21)
@@ -3616,12 +3797,20 @@
         static boolean isPowerSaveMode(PowerManager powerManager) {
             return powerManager.isPowerSaveMode();
         }
+
+        @DoNotInline
+        static String toLanguageTag(Locale locale) {
+            return locale.toLanguageTag();
+        }
     }
 
     @RequiresApi(24)
     static class Api24Impl {
         private Api24Impl() { }
 
+        // Most methods of LocaleListCompat requires a minimum API of 24 to be used and these are
+        // the helper implementations of those methods, used to indirectly invoke them in our code.
+        @DoNotInline
         static void generateConfigDelta_locale(@NonNull Configuration base,
                 @NonNull Configuration change, @NonNull Configuration delta) {
             final LocaleList baseLocales = base.getLocales();
@@ -3631,6 +3820,21 @@
                 delta.locale = change.locale;
             }
         }
+
+        @DoNotInline
+        static LocaleListCompat getLocales(Configuration configuration) {
+            return LocaleListCompat.forLanguageTags(configuration.getLocales().toLanguageTags());
+        }
+
+        @DoNotInline
+        static void setLocales(Configuration configuration, LocaleListCompat locales) {
+            configuration.setLocales(LocaleList.forLanguageTags(locales.toLanguageTags()));
+        }
+
+        @DoNotInline
+        public static void setDefaultLocales(LocaleListCompat locales) {
+            LocaleList.setDefault(LocaleList.forLanguageTags(locales.toLanguageTags()));
+        }
     }
 
     @RequiresApi(26)
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppLocalesMetadataHolderService.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppLocalesMetadataHolderService.java
new file mode 100644
index 0000000..5f2668f
--- /dev/null
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppLocalesMetadataHolderService.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2022 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.appcompat.app;
+
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.os.Build;
+import android.os.IBinder;
+
+import androidx.annotation.DoNotInline;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.core.os.LocaleListCompat;
+
+/**
+ * A placeholder service to avoid adding application-level metadata. The service
+ * is only used to expose metadata defined in the library's manifest. It is
+ * never invoked.
+ *
+ * <p>This metadata boolean collected from the key "autoStoreLocales" is used as an opt-in from
+ * the developers to automatically store locales provided by them through the API
+ * {@link AppCompatDelegate#setApplicationLocales(LocaleListCompat)}.</p>
+ */
+public final class AppLocalesMetadataHolderService extends Service {
+    public AppLocalesMetadataHolderService() {}
+
+    @NonNull
+    @Override
+    public IBinder onBind(@SuppressWarnings("InvalidNullabilityOverride") @NonNull Intent intent) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns the {@link ServiceInfo} for the declared {@link AppLocalesMetadataHolderService}.
+     *
+     * <p>This serviceInfo contains the attribute "autoStoreLocales", its value being a boolean
+     * that informs us if the developer wants us to handle the storage of locales or not.</p>
+     */
+    @NonNull
+    @SuppressWarnings("deprecation") // GET_DISABLED_COMPONENTS, getServiceInfo
+    public static ServiceInfo getServiceInfo(@NonNull Context context) throws
+            PackageManager.NameNotFoundException {
+        int flags = PackageManager.GET_META_DATA;
+        // The service is marked as disabled so we need to include the following flags.
+        if (Build.VERSION.SDK_INT >= 24) {
+            flags |= Api24Impl.getDisabledComponentFlag();
+        } else {
+            flags |= PackageManager.GET_DISABLED_COMPONENTS;
+        }
+
+        return context.getPackageManager().getServiceInfo(
+                new ComponentName(context, AppLocalesMetadataHolderService.class), flags);
+    }
+
+    @RequiresApi(24)
+    private static class Api24Impl {
+        @DoNotInline
+        static int getDisabledComponentFlag() {
+            return PackageManager.MATCH_DISABLED_COMPONENTS;
+        }
+    }
+}
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppLocalesStorageHelper.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppLocalesStorageHelper.java
new file mode 100644
index 0000000..d30f599
--- /dev/null
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppLocalesStorageHelper.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2022 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.appcompat.app;
+
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.content.pm.PackageManager.DONT_KILL_APP;
+
+import static androidx.appcompat.app.AppCompatDelegate.getApplicationLocales;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Log;
+import android.util.Xml;
+
+import androidx.annotation.NonNull;
+import androidx.core.os.LocaleListCompat;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Queue;
+import java.util.concurrent.Executor;
+
+/**
+ * Helper class to manage storage of locales in app's persistent files.
+ */
+class AppLocalesStorageHelper {
+    static final String APPLICATION_LOCALES_RECORD_FILE =
+            "androidx.appcompat.app.AppCompatDelegate.application_locales_record_file";
+    static final String LOCALE_RECORD_ATTRIBUTE_TAG = "application_locales";
+    static final String LOCALE_RECORD_FILE_TAG = "locales";
+    static final String APP_LOCALES_META_DATA_HOLDER_SERVICE_NAME = "androidx.appcompat.app"
+            + ".AppLocalesMetadataHolderService";
+    static final String TAG = "AppLocalesStorageHelper";
+
+    private AppLocalesStorageHelper() {}
+
+    /**
+     * Returns app locales after reading from storage, fetched using the application context.
+     */
+    @NonNull
+    static String readLocales(@NonNull Context context) {
+        String appLocales = "";
+
+        FileInputStream fis;
+        try {
+            fis = context.openFileInput(APPLICATION_LOCALES_RECORD_FILE);
+        } catch (FileNotFoundException fnfe) {
+            Log.w(TAG, "Reading app Locales : Locales record file not found: "
+                    + APPLICATION_LOCALES_RECORD_FILE);
+            return appLocales;
+        }
+        try {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(fis, "UTF-8");
+            int type;
+            int outerDepth = parser.getDepth();
+            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                    continue;
+                }
+
+                String tagName = parser.getName();
+                if (tagName.equals(LOCALE_RECORD_FILE_TAG)) {
+                    appLocales =  parser.getAttributeValue(/*namespace= */ null,
+                            LOCALE_RECORD_ATTRIBUTE_TAG);
+                    break;
+                }
+            }
+        } catch (XmlPullParserException | IOException e) {
+            Log.w(TAG,
+                    "Reading app Locales : Unable to parse through file :"
+                            + APPLICATION_LOCALES_RECORD_FILE);
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException e) {
+                    /* ignore */
+                }
+            }
+        }
+
+        if (!appLocales.isEmpty()) {
+            Log.d(TAG,
+                    "Reading app Locales : Locales read from file: "
+                            + APPLICATION_LOCALES_RECORD_FILE + " ," + " appLocales: "
+                            + appLocales);
+        } else {
+            context.deleteFile(APPLICATION_LOCALES_RECORD_FILE);
+        }
+        return appLocales;
+    }
+
+    /**
+     * Stores the provided locales in internal app file, using the application context.
+     */
+    static void persistLocales(@NonNull Context context, @NonNull String locales) {
+        if (locales.equals("")) {
+            context.deleteFile(APPLICATION_LOCALES_RECORD_FILE);
+            return;
+        }
+
+        FileOutputStream fos;
+        try {
+            fos = context.openFileOutput(APPLICATION_LOCALES_RECORD_FILE, Context.MODE_PRIVATE);
+        } catch (FileNotFoundException fnfe) {
+            Log.w(TAG, String.format("Storing App Locales : FileNotFoundException: Cannot open "
+                    + "file %s for writing ", APPLICATION_LOCALES_RECORD_FILE));
+            return;
+        }
+        XmlSerializer serializer = Xml.newSerializer();
+        try {
+            serializer.setOutput(fos, /* encoding= */ null);
+            serializer.startDocument("UTF-8", true);
+            serializer.startTag(/* namespace= */ null, LOCALE_RECORD_FILE_TAG);
+            serializer.attribute(/* namespace= */ null, LOCALE_RECORD_ATTRIBUTE_TAG, locales);
+            serializer.endTag(/* namespace= */ null, LOCALE_RECORD_FILE_TAG);
+            serializer.endDocument();
+            Log.d(TAG, "Storing App Locales : app-locales: "
+                    + locales + " persisted successfully.");
+        } catch (Exception e) {
+            Log.w(TAG, "Storing App Locales : Failed to persist app-locales: "
+                    + locales, e);
+        } finally {
+            if (fos != null) {
+                try {
+                    fos.close();
+                } catch (IOException e) {
+                    /* ignore */
+                }
+            }
+        }
+    }
+
+    /**
+     * Syncs app-specific locales from androidX to framework. This is used to maintain a smooth
+     * transition for a device that updates from pre-T API versions to T.
+     *
+     * <p><b>NOTE:</b> This should only be called when auto-storage is opted-in. This method
+     * uses the meta-data service provided during the opt-in and hence if the service is not found
+     * this method will throw an error.</p>
+     */
+    static void syncLocalesToFramework(Context context) {
+        ComponentName app_locales_component = new ComponentName(
+                context, APP_LOCALES_META_DATA_HOLDER_SERVICE_NAME);
+
+        if (context.getPackageManager().getComponentEnabledSetting(app_locales_component)
+                != COMPONENT_ENABLED_STATE_ENABLED) {
+            AppCompatDelegate.setAppContext(context);
+            // ComponentEnabledSetting for the app component app_locales_component is used as a
+            // marker to represent that the locales has been synced from AndroidX to framework
+            // If this marker is found in ENABLED state then we do not need to sync again.
+            if (getApplicationLocales().isEmpty()) {
+                // We check if some locales are applied by the framework or not (this is done to
+                // ensure that we don't overwrite newer locales set by the framework). If no
+                // app-locales are found then we need to sync the app-specific locales from androidX
+                // to framework.
+
+                String appLocales = readLocales(context);
+                // if locales are present in storage, call the setApplicationLocales() API. As the
+                // API version is >= 33, this call will be directed to the framework API and the
+                // locales will be persisted there.
+                AppCompatDelegate.setApplicationLocales(
+                        LocaleListCompat.forLanguageTags(appLocales));
+            }
+            // setting ComponentEnabledSetting for app component using
+            // AppLocalesMetadataHolderService (used only for locales, thus minimizing
+            // the chances of conflicts). Setting it as ENABLED marks the success of app-locales
+            // sync from AndroidX to framework.
+            // Flag DONT_KILL_APP indicates that you don't want to kill the app containing the
+            // component.
+            context.getPackageManager().setComponentEnabledSetting(app_locales_component,
+                    COMPONENT_ENABLED_STATE_ENABLED, /* flags= */ DONT_KILL_APP);
+        }
+    }
+
+    /**
+     * Implementation of {@link java.util.concurrent.Executor} that executes each runnable on a
+     * new thread.
+     */
+    static class ThreadPerTaskExecutor implements Executor {
+        @Override
+        public void execute(Runnable r) {
+            new Thread(r).start();
+        }
+    }
+
+    /**
+     * Implementation of {@link java.util.concurrent.Executor} that executes runnables serially
+     * by synchronizing the {@link Executor#execute(Runnable)} method and maintaining a tasks
+     * queue.
+     */
+    static class SerialExecutor implements Executor {
+        private final Object mLock = new Object();
+        final Queue<Runnable> mTasks = new ArrayDeque<>();
+        final Executor mExecutor;
+        Runnable mActive;
+
+        SerialExecutor(Executor executor) {
+            this.mExecutor = executor;
+        }
+
+        @Override
+        public void execute(final Runnable r) {
+            synchronized (mLock) {
+                mTasks.add(() -> {
+                    try {
+                        r.run();
+                    } finally {
+                        scheduleNext();
+                    }
+                });
+                if (mActive == null) {
+                    scheduleNext();
+                }
+            }
+        }
+
+        protected void scheduleNext() {
+            synchronized (mLock) {
+                if ((mActive = mTasks.poll()) != null) {
+                    mExecutor.execute(mActive);
+                }
+            }
+        }
+    }
+}
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/LocaleOverlayHelper.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/LocaleOverlayHelper.java
new file mode 100644
index 0000000..9684b92
--- /dev/null
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/LocaleOverlayHelper.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 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.
+ * 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.appcompat.app;
+
+import android.os.LocaleList;
+
+import androidx.annotation.RequiresApi;
+import androidx.core.os.LocaleListCompat;
+
+import java.util.LinkedHashSet;
+import java.util.Locale;
+import java.util.Set;
+
+/**
+ * Static utilities to overlay locales on top of another LocaleListCompat.
+ *
+ * <p>This is used to overlay application-specific locales on top of
+ * system locales.</p>
+ */
+@RequiresApi(24)
+final class LocaleOverlayHelper {
+
+    private LocaleOverlayHelper() {}
+
+    /**
+     * Combines the overlay locales and base locales.
+     *
+     * @return the combined {@link LocaleListCompat} if the overlay locales is not empty/null else
+     * returns an empty LocaleListCompat.
+     */
+    static LocaleListCompat combineLocalesIfOverlayExists(LocaleListCompat overlayLocales,
+            LocaleListCompat baseLocales) {
+        if (overlayLocales == null || overlayLocales.isEmpty()) {
+            return LocaleListCompat.getEmptyLocaleList();
+        }
+        return combineLocales(overlayLocales, baseLocales);
+    }
+
+    static LocaleListCompat combineLocalesIfOverlayExists(LocaleList overlayLocales,
+            LocaleList baseLocales) {
+        if (overlayLocales == null || overlayLocales.isEmpty()) {
+            return LocaleListCompat.getEmptyLocaleList();
+        }
+        return combineLocales(LocaleListCompat.wrap(overlayLocales),
+                LocaleListCompat.wrap(baseLocales));
+    }
+
+    /**
+     * Creates a combined {@link LocaleListCompat} by placing overlay locales before base
+     * locales and dropping duplicates from the base locales.
+     */
+    private static LocaleListCompat combineLocales(LocaleListCompat overlayLocales,
+            LocaleListCompat baseLocales) {
+        // using LinkedHashSet to drop duplicates.
+        Set<Locale> combinedLocales = new LinkedHashSet<>();
+        for (int i = 0; i < overlayLocales.size() + baseLocales.size(); i++) {
+            Locale currLocale;
+            if (i < overlayLocales.size()) {
+                currLocale = overlayLocales.get(i);
+            } else {
+                currLocale = baseLocales.get(i - overlayLocales.size());
+            }
+            if (currLocale != null) {
+                combinedLocales.add(currLocale);
+            }
+        }
+        return LocaleListCompat.create(combinedLocales.toArray(
+                new Locale[combinedLocales.size()]));
+    }
+}
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ActivityChooserModel.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ActivityChooserModel.java
index 89e3bb9..34a8e20 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ActivityChooserModel.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ActivityChooserModel.java
@@ -683,6 +683,7 @@
      *
      * @return Whether loading was performed.
      */
+    @SuppressWarnings("deprecation")
     private boolean loadActivitiesIfNeeded() {
         if (mReloadActivities && mIntent != null) {
             mReloadActivities = false;
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatSpinner.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatSpinner.java
index 6e9c5ba..6cc5e8b 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatSpinner.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/AppCompatSpinner.java
@@ -59,6 +59,7 @@
 import androidx.appcompat.content.res.AppCompatResources;
 import androidx.appcompat.view.ContextThemeWrapper;
 import androidx.appcompat.view.menu.ShowableListMenu;
+import androidx.core.util.ObjectsCompat;
 import androidx.core.view.TintableBackgroundView;
 import androidx.core.view.ViewCompat;
 import androidx.resourceinspection.annotation.AppCompatShadowedAttributes;
@@ -1129,7 +1130,7 @@
                 @NonNull android.widget.ThemedSpinnerAdapter themedSpinnerAdapter,
                 @Nullable Resources.Theme theme
         ) {
-            if (themedSpinnerAdapter.getDropDownViewTheme() != theme) {
+            if (!ObjectsCompat.equals(themedSpinnerAdapter.getDropDownViewTheme(), theme)) {
                 themedSpinnerAdapter.setDropDownViewTheme(theme);
             }
         }
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/DropDownListView.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/DropDownListView.java
index ff70a9c..d54e587 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/DropDownListView.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/DropDownListView.java
@@ -23,6 +23,7 @@
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -62,8 +63,6 @@
 
     private int mMotionPosition;
 
-    private Field mIsChildViewEnabled;
-
     private GateKeeperDrawable mSelector;
 
     /*
@@ -126,15 +125,23 @@
         super(context, null, R.attr.dropDownListViewStyle);
         mHijackFocus = hijackFocus;
         setCacheColorHint(0); // Transparent, since the background drawable could be anything.
+    }
 
-        try {
-            mIsChildViewEnabled = AbsListView.class.getDeclaredField("mIsChildViewEnabled");
-            mIsChildViewEnabled.setAccessible(true);
-        } catch (NoSuchFieldException e) {
-            e.printStackTrace();
+    private boolean superIsSelectedChildViewEnabled() {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return Api33Impl.isSelectedChildViewEnabled(this);
+        } else {
+            return PreApi33Impl.isSelectedChildViewEnabled(this);
         }
     }
 
+    private void superSetSelectedChildViewEnabled(boolean enabled) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            Api33Impl.setSelectedChildViewEnabled(this, enabled);
+        } else {
+            PreApi33Impl.setSelectedChildViewEnabled(this, enabled);
+        }
+    }
 
     @Override
     public boolean isInTouchMode() {
@@ -624,18 +631,14 @@
         selectorRect.right += mSelectionRightPadding;
         selectorRect.bottom += mSelectionBottomPadding;
 
-        try {
-            // AbsListView.mIsChildViewEnabled controls the selector's state so we need to
-            // modify its value
-            final boolean isChildViewEnabled = mIsChildViewEnabled.getBoolean(this);
-            if (sel.isEnabled() != isChildViewEnabled) {
-                mIsChildViewEnabled.set(this, !isChildViewEnabled);
-                if (position != INVALID_POSITION) {
-                    refreshDrawableState();
-                }
+        // AbsListView.mIsChildViewEnabled controls the selector's state so we need to
+        // modify its value
+        final boolean isChildViewEnabled = superIsSelectedChildViewEnabled();
+        if (sel.isEnabled() != isChildViewEnabled) {
+            superSetSelectedChildViewEnabled(!isChildViewEnabled);
+            if (position != INVALID_POSITION) {
+                refreshDrawableState();
             }
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
         }
     }
 
@@ -803,4 +806,66 @@
             view.drawableHotspotChanged(x, y);
         }
     }
+
+    // TODO(b/221852137): Use @DeprecatedSinceApi(33).
+    @SuppressWarnings({"JavaReflectionMemberAccess", "CatchAndPrintStackTrace"})
+    static class PreApi33Impl {
+        private static final Field sIsChildViewEnabled;
+
+        static {
+            Field isChildViewEnabled = null;
+
+            try {
+                isChildViewEnabled = AbsListView.class.getDeclaredField("mIsChildViewEnabled");
+                isChildViewEnabled.setAccessible(true);
+            } catch (NoSuchFieldException e) {
+                e.printStackTrace();
+            }
+
+            sIsChildViewEnabled = isChildViewEnabled;
+        }
+
+        private PreApi33Impl() {
+            // This class is not instantiable.
+        }
+
+        static boolean isSelectedChildViewEnabled(AbsListView view) {
+            if (sIsChildViewEnabled != null) {
+                try {
+                    return sIsChildViewEnabled.getBoolean(view);
+                } catch (IllegalAccessException e) {
+                    e.printStackTrace();
+                }
+            }
+
+            return false;
+        }
+
+        static void setSelectedChildViewEnabled(AbsListView view, boolean enabled) {
+            if (sIsChildViewEnabled != null) {
+                try {
+                    sIsChildViewEnabled.set(view, enabled);
+                } catch (IllegalAccessException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    static class Api33Impl {
+        private Api33Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static boolean isSelectedChildViewEnabled(AbsListView view) {
+            return view.isSelectedChildViewEnabled();
+        }
+
+        @DoNotInline
+        static void setSelectedChildViewEnabled(AbsListView view, boolean enabled) {
+            view.setSelectedChildViewEnabled(enabled);
+        }
+    }
 }
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/SearchView.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/SearchView.java
index 072c94a..3bd4492 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/SearchView.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/SearchView.java
@@ -900,6 +900,7 @@
         updateSubmitArea();
     }
 
+    @SuppressWarnings("deprecation")
     private boolean hasVoiceSearch() {
         if (mSearchable != null && mSearchable.getVoiceSearchEnabled()) {
             Intent testIntent = null;
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ThemedSpinnerAdapter.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ThemedSpinnerAdapter.java
index 173e289..77e9dae 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ThemedSpinnerAdapter.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ThemedSpinnerAdapter.java
@@ -123,7 +123,7 @@
         public void setDropDownViewTheme(@Nullable Resources.Theme theme) {
             if (theme == null) {
                 mDropDownInflater = null;
-            } else if (theme == mContext.getTheme()) {
+            } else if (theme.equals(mContext.getTheme())) {
                 mDropDownInflater = mInflater;
             } else {
                 final Context context = new ContextThemeWrapper(mContext, theme);
diff --git a/appsearch/appsearch-debug-view/samples/src/main/java/androidx/appsearch/debugview/samples/NotesAppSearchManager.java b/appsearch/appsearch-debug-view/samples/src/main/java/androidx/appsearch/debugview/samples/NotesAppSearchManager.java
index 7aba8a7..2628b2e 100644
--- a/appsearch/appsearch-debug-view/samples/src/main/java/androidx/appsearch/debugview/samples/NotesAppSearchManager.java
+++ b/appsearch/appsearch-debug-view/samples/src/main/java/androidx/appsearch/debugview/samples/NotesAppSearchManager.java
@@ -93,7 +93,7 @@
             PutDocumentsRequest request = new PutDocumentsRequest.Builder().addDocuments(notes)
                     .build();
             return Futures.transformAsync(mAppSearchSessionFuture,
-                    session -> session.put(request), mExecutor);
+                    session -> session.putAsync(request), mExecutor);
         } catch (Exception e) {
             return Futures.immediateFailedFuture(e);
         }
@@ -112,7 +112,7 @@
     }
 
     private ListenableFuture<AppSearchSession> createLocalSession() {
-        return LocalStorage.createSearchSession(
+        return LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(mContext, DB_NAME)
                         .build()
         );
@@ -122,7 +122,7 @@
         SetSchemaRequest request =
                 new SetSchemaRequest.Builder().setForceOverride(FORCE_OVERRIDE).build();
         return Futures.transformAsync(mAppSearchSessionFuture,
-                session -> session.setSchema(request),
+                session -> session.setSchemaAsync(request),
                 mExecutor);
     }
 
@@ -131,7 +131,7 @@
             SetSchemaRequest request = new SetSchemaRequest.Builder().addDocumentClasses(Note.class)
                     .build();
             return Futures.transformAsync(mAppSearchSessionFuture,
-                    session -> session.setSchema(request), mExecutor);
+                    session -> session.setSchemaAsync(request), mExecutor);
         } catch (AppSearchException e) {
             return Futures.immediateFailedFuture(e);
         }
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/DebugAppSearchManager.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/DebugAppSearchManager.java
index 720d679..fce8a0d 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/DebugAppSearchManager.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/DebugAppSearchManager.java
@@ -81,7 +81,7 @@
      *                            storage as the storage type for debugging.
      */
     @NonNull
-    public static ListenableFuture<DebugAppSearchManager> create(
+    public static ListenableFuture<DebugAppSearchManager> createAsync(
             @NonNull Context context,
             @NonNull ExecutorService executor, @NonNull String databaseName,
             @AppSearchDebugActivity.StorageType int storageType) throws AppSearchException {
@@ -98,14 +98,13 @@
             case AppSearchDebugActivity.STORAGE_TYPE_LOCAL:
                 debugAppSearchManagerListenableFuture =
                         Futures.transform(
-                                debugAppSearchManager.initializeLocalStorage(databaseName),
+                                debugAppSearchManager.initializeLocalStorageAsync(databaseName),
                                 unused -> debugAppSearchManager, executor);
                 break;
             case AppSearchDebugActivity.STORAGE_TYPE_PLATFORM:
                 if (Build.VERSION.SDK_INT >= 31) {
-                    debugAppSearchManagerListenableFuture =
-                            Futures.transform(
-                                    debugAppSearchManager.initializePlatformStorage(databaseName),
+                    debugAppSearchManagerListenableFuture = Futures.transform(
+                            debugAppSearchManager.initializePlatformStorageAsync(databaseName),
                                     unused -> debugAppSearchManager, executor);
                 } else {
                     throw new AppSearchException(AppSearchResult.RESULT_INVALID_ARGUMENT,
@@ -130,7 +129,7 @@
      * {@link #getNextPage} to retrieve the {@link GenericDocument} objects for each page.
      */
     @NonNull
-    public ListenableFuture<SearchResults> getAllDocumentsSearchResults() {
+    public ListenableFuture<SearchResults> getAllDocumentsSearchResultsAsync() {
         SearchSpec searchSpec = new SearchSpec.Builder()
                 .setResultCountPerPage(PAGE_SIZE)
                 .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
@@ -151,10 +150,11 @@
      *                {@link GenericDocument} objects.
      */
     @NonNull
-    public ListenableFuture<List<GenericDocument>> getNextPage(@NonNull SearchResults results) {
+    public ListenableFuture<List<GenericDocument>> getNextPageAsync(
+            @NonNull SearchResults results) {
         Preconditions.checkNotNull(results);
 
-        return Futures.transform(results.getNextPage(),
+        return Futures.transform(results.getNextPageAsync(),
                 DebugAppSearchManager::convertResultsToGenericDocuments, mExecutor);
     }
 
@@ -162,7 +162,7 @@
      * Gets a document from the AppSearch database by namespace and ID.
      */
     @NonNull
-    public ListenableFuture<GenericDocument> getDocument(@NonNull String namespace,
+    public ListenableFuture<GenericDocument> getDocumentAsync(@NonNull String namespace,
             @NonNull String id) {
         Preconditions.checkNotNull(id);
         Preconditions.checkNotNull(namespace);
@@ -170,7 +170,7 @@
                 new GetByDocumentIdRequest.Builder(namespace).addIds(id).build();
 
         return Futures.transformAsync(mAppSearchSessionFuture,
-                session -> Futures.transform(session.getByDocumentId(request),
+                session -> Futures.transform(session.getByDocumentIdAsync(request),
                         response -> response.getSuccesses().get(id), mExecutor), mExecutor);
     }
 
@@ -178,9 +178,9 @@
      * Gets the schema of the AppSearch database.
      */
     @NonNull
-    public ListenableFuture<GetSchemaResponse> getSchema() {
+    public ListenableFuture<GetSchemaResponse> getSchemaAsync() {
         return Futures.transformAsync(mAppSearchSessionFuture,
-                session -> session.getSchema(), mExecutor);
+                session -> session.getSchemaAsync(), mExecutor);
     }
 
     /**
@@ -195,9 +195,9 @@
     }
 
     @NonNull
-    private ListenableFuture<AppSearchSession> initializeLocalStorage(
+    private ListenableFuture<AppSearchSession> initializeLocalStorageAsync(
             @NonNull String databaseName) {
-        mAppSearchSessionFuture.setFuture(LocalStorage.createSearchSession(
+        mAppSearchSessionFuture.setFuture(LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(mContext, databaseName)
                         .build())
         );
@@ -206,9 +206,9 @@
 
     @NonNull
     @RequiresApi(Build.VERSION_CODES.S)
-    private ListenableFuture<AppSearchSession> initializePlatformStorage(
+    private ListenableFuture<AppSearchSession> initializePlatformStorageAsync(
             @NonNull String databaseName) {
-        mAppSearchSessionFuture.setFuture(PlatformStorage.createSearchSession(
+        mAppSearchSessionFuture.setFuture(PlatformStorage.createSearchSessionAsync(
                 new PlatformStorage.SearchContext.Builder(mContext, databaseName)
                         .build())
         );
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentListModel.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentListModel.java
index 5a23cb0..6425c63 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentListModel.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentListModel.java
@@ -76,7 +76,7 @@
      */
     @NonNull
     public LiveData<SearchResults> getAllDocumentsSearchResults() {
-        Futures.addCallback(mDebugAppSearchManager.getAllDocumentsSearchResults(),
+        Futures.addCallback(mDebugAppSearchManager.getAllDocumentsSearchResultsAsync(),
                 new FutureCallback<SearchResults>() {
                     @Override
                     public void onSuccess(SearchResults result) {
@@ -107,7 +107,7 @@
     @NonNull
     public LiveData<List<GenericDocument>> addAdditionalResultsPage(
             @NonNull SearchResults results) {
-        Futures.addCallback(mDebugAppSearchManager.getNextPage(results),
+        Futures.addCallback(mDebugAppSearchManager.getNextPageAsync(results),
                 new FutureCallback<List<GenericDocument>>() {
                     @Override
                     public void onSuccess(List<GenericDocument> result) {
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentModel.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentModel.java
index a8c03dc..41d2ed1 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentModel.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentModel.java
@@ -61,7 +61,7 @@
      */
     @NonNull
     public LiveData<GenericDocument> getDocument(@NonNull String namespace, @NonNull String id) {
-        Futures.addCallback(mDebugAppSearchManager.getDocument(namespace, id),
+        Futures.addCallback(mDebugAppSearchManager.getDocumentAsync(namespace, id),
                 new FutureCallback<GenericDocument>() {
                     @Override
                     public void onSuccess(GenericDocument result) {
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/SchemaTypeListModel.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/SchemaTypeListModel.java
index 16e0b66..70cc1ee 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/SchemaTypeListModel.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/SchemaTypeListModel.java
@@ -90,7 +90,7 @@
      */
     @NonNull
     private LiveData<GetSchemaResponse> getSchema() {
-        Futures.addCallback(mDebugAppSearchManager.getSchema(),
+        Futures.addCallback(mDebugAppSearchManager.getSchemaAsync(),
                 new FutureCallback<GetSchemaResponse>() {
                     @Override
                     public void onSuccess(GetSchemaResponse result) {
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/AppSearchDebugActivity.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/AppSearchDebugActivity.java
index 20ea01f..3174e2d 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/AppSearchDebugActivity.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/AppSearchDebugActivity.java
@@ -97,7 +97,7 @@
         @StorageType int storageType =
                 getIntent().getExtras().getInt(STORAGE_TYPE_INTENT_KEY);
         try {
-            mDebugAppSearchManager = DebugAppSearchManager.create(
+            mDebugAppSearchManager = DebugAppSearchManager.createAsync(
                     getApplicationContext(), mBackgroundExecutor, mDbName, storageType);
         } catch (AppSearchException e) {
             Toast.makeText(getApplicationContext(),
diff --git a/appsearch/appsearch-ktx/src/androidTest/java/AnnotationProcessorKtTest.kt b/appsearch/appsearch-ktx/src/androidTest/java/AnnotationProcessorKtTest.kt
index 7636104..85eb735 100644
--- a/appsearch/appsearch-ktx/src/androidTest/java/AnnotationProcessorKtTest.kt
+++ b/appsearch/appsearch-ktx/src/androidTest/java/AnnotationProcessorKtTest.kt
@@ -43,7 +43,7 @@
     @Before
     public fun setUp() {
         val context = ApplicationProvider.getApplicationContext<Context>()
-        session = LocalStorage.createSearchSession(
+        session = LocalStorage.createSearchSessionAsync(
             LocalStorage.SearchContext.Builder(context, DB_NAME).build()
         ).get()
 
@@ -59,7 +59,7 @@
     }
 
     private fun cleanup() {
-        session.setSchema(SetSchemaRequest.Builder().setForceOverride(true).build()).get()
+        session.setSchemaAsync(SetSchemaRequest.Builder().setForceOverride(true).build()).get()
     }
 
     @Document
@@ -250,7 +250,7 @@
 
     @Test
     fun testAnnotationProcessor() {
-        session.setSchema(
+        session.setSchemaAsync(
             SetSchemaRequest.Builder()
                 .addDocumentClasses(Card::class.java, Gift::class.java).build()
         ).get()
@@ -260,7 +260,7 @@
 
         // Index the Gift document and query it.
         checkIsBatchResultSuccess(
-            session.put(
+            session.putAsync(
                 PutDocumentsRequest.Builder().addDocuments(inputDocument).build()
             )
         )
diff --git a/appsearch/appsearch-local-storage/api/current.txt b/appsearch/appsearch-local-storage/api/current.txt
index 5eb0af5..94465dd 100644
--- a/appsearch/appsearch-local-storage/api/current.txt
+++ b/appsearch/appsearch-local-storage/api/current.txt
@@ -2,7 +2,8 @@
 package androidx.appsearch.localstorage {
 
   public class LocalStorage {
-    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSession(androidx.appsearch.localstorage.LocalStorage.SearchContext);
+    method @Deprecated public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSession(androidx.appsearch.localstorage.LocalStorage.SearchContext);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSessionAsync(androidx.appsearch.localstorage.LocalStorage.SearchContext);
   }
 
   public static final class LocalStorage.SearchContext {
diff --git a/appsearch/appsearch-local-storage/api/public_plus_experimental_current.txt b/appsearch/appsearch-local-storage/api/public_plus_experimental_current.txt
index 5eb0af5..94465dd 100644
--- a/appsearch/appsearch-local-storage/api/public_plus_experimental_current.txt
+++ b/appsearch/appsearch-local-storage/api/public_plus_experimental_current.txt
@@ -2,7 +2,8 @@
 package androidx.appsearch.localstorage {
 
   public class LocalStorage {
-    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSession(androidx.appsearch.localstorage.LocalStorage.SearchContext);
+    method @Deprecated public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSession(androidx.appsearch.localstorage.LocalStorage.SearchContext);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSessionAsync(androidx.appsearch.localstorage.LocalStorage.SearchContext);
   }
 
   public static final class LocalStorage.SearchContext {
diff --git a/appsearch/appsearch-local-storage/api/restricted_current.txt b/appsearch/appsearch-local-storage/api/restricted_current.txt
index 5eb0af5..94465dd 100644
--- a/appsearch/appsearch-local-storage/api/restricted_current.txt
+++ b/appsearch/appsearch-local-storage/api/restricted_current.txt
@@ -2,7 +2,8 @@
 package androidx.appsearch.localstorage {
 
   public class LocalStorage {
-    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSession(androidx.appsearch.localstorage.LocalStorage.SearchContext);
+    method @Deprecated public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSession(androidx.appsearch.localstorage.LocalStorage.SearchContext);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSessionAsync(androidx.appsearch.localstorage.LocalStorage.SearchContext);
   }
 
   public static final class LocalStorage.SearchContext {
diff --git a/appsearch/appsearch-local-storage/build.gradle b/appsearch/appsearch-local-storage/build.gradle
index 268af48..d723e00 100644
--- a/appsearch/appsearch-local-storage/build.gradle
+++ b/appsearch/appsearch-local-storage/build.gradle
@@ -44,12 +44,11 @@
     defaultConfig {
         externalNativeBuild {
             cmake {
-                cppFlags "-std=c++17"
                 arguments "-DCMAKE_VERBOSE_MAKEFILE=ON"
                 targets "icing"
             }
         }
-	multiDexEnabled true
+        multiDexEnabled true
     }
     externalNativeBuild {
         cmake {
@@ -72,9 +71,9 @@
     api("androidx.annotation:annotation:1.1.0")
 
     implementation(project(":appsearch:appsearch"))
+    implementation('androidx.collection:collection:1.2.0')
     implementation("androidx.concurrent:concurrent-futures:1.0.0")
     implementation("androidx.core:core:1.2.0")
-    implementation('androidx.collection:collection:1.0.0')
 
     androidTestImplementation project(':appsearch:appsearch-test-util')
     androidTestImplementation(libs.multidex)
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchImplTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchImplTest.java
index 961543b..c3d5036a 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchImplTest.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchImplTest.java
@@ -25,20 +25,29 @@
 import static org.junit.Assert.assertThrows;
 
 import android.content.Context;
-import android.os.Process;
 
 import androidx.appsearch.app.AppSearchResult;
 import androidx.appsearch.app.AppSearchSchema;
 import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.GetSchemaResponse;
+import androidx.appsearch.app.PackageIdentifier;
 import androidx.appsearch.app.SearchResult;
 import androidx.appsearch.app.SearchResultPage;
 import androidx.appsearch.app.SearchSpec;
 import androidx.appsearch.app.SetSchemaResponse;
 import androidx.appsearch.app.StorageInfo;
+import androidx.appsearch.app.VisibilityDocument;
 import androidx.appsearch.exceptions.AppSearchException;
 import androidx.appsearch.localstorage.stats.InitializeStats;
 import androidx.appsearch.localstorage.stats.OptimizeStats;
 import androidx.appsearch.localstorage.util.PrefixUtil;
+import androidx.appsearch.localstorage.visibilitystore.CallerAccess;
+import androidx.appsearch.localstorage.visibilitystore.VisibilityChecker;
+import androidx.appsearch.localstorage.visibilitystore.VisibilityStore;
+import androidx.appsearch.observer.DocumentChangeInfo;
+import androidx.appsearch.observer.ObserverSpec;
+import androidx.appsearch.observer.SchemaChangeInfo;
+import androidx.appsearch.testutil.TestObserverCallback;
 import androidx.collection.ArrayMap;
 import androidx.collection.ArraySet;
 import androidx.test.core.app.ApplicationProvider;
@@ -58,6 +67,7 @@
 import com.google.android.icing.proto.TermMatchType;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.MoreExecutors;
 
 import org.junit.After;
 import org.junit.Before;
@@ -72,6 +82,7 @@
 import java.util.Map;
 import java.util.Set;
 
+@SuppressWarnings("GuardedBy")
 public class AppSearchImplTest {
     /**
      * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
@@ -80,6 +91,12 @@
     @Rule
     public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
     private File mAppSearchDir;
+
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+
+    // The caller access for this package
+    private final CallerAccess mSelfCallerAccess = new CallerAccess(mContext.getPackageName());
+
     private AppSearchImpl mAppSearchImpl;
 
     @Before
@@ -88,7 +105,9 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+                /*initStatsBuilder=*/ null,
+                ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
     }
 
     @After
@@ -366,16 +385,19 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
 
         // Insert a document and then remove it to generate garbage.
         GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
         mAppSearchImpl.remove("package", "database", "namespace", "id",
                 /*removeStatsBuilder=*/ null);
 
@@ -409,17 +431,14 @@
     @Test
     public void testReset() throws Exception {
         // Insert schema
-        Context context = ApplicationProvider.getApplicationContext();
         List<AppSearchSchema> schemas = ImmutableList.of(
                 new AppSearchSchema.Builder("Type1").build(),
                 new AppSearchSchema.Builder("Type2").build());
         mAppSearchImpl.setSchema(
-                context.getPackageName(),
+                mContext.getPackageName(),
                 "database1",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -428,9 +447,10 @@
         GenericDocument validDoc =
                 new GenericDocument.Builder<>("namespace1", "id1", "Type1").build();
         mAppSearchImpl.putDocument(
-                context.getPackageName(),
+                mContext.getPackageName(),
                 "database1",
                 validDoc,
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/null);
 
         // Query it via global query. We use the same code again later so this is to make sure we
@@ -438,10 +458,7 @@
         SearchResultPage results = mAppSearchImpl.globalQuery(
                 /*queryExpression=*/ "",
                 new SearchSpec.Builder().addFilterSchemas("Type1").build(),
-                context.getPackageName(),
-                /*visibilityStore=*/ null,
-                Process.INVALID_UID,
-                /*callerHasSystemAccess=*/ false,
+                mSelfCallerAccess,
                 /*logger=*/ null);
         assertThat(results.getResults()).hasSize(1);
         assertThat(results.getResults().get(0).getGenericDocument()).isEqualTo(validDoc);
@@ -450,7 +467,7 @@
         DocumentProto invalidDoc = DocumentProto.newBuilder()
                 .setNamespace("invalidNamespace")
                 .setUri("id2")
-                .setSchema(context.getPackageName() + "$database1/Type1")
+                .setSchema(mContext.getPackageName() + "$database1/Type1")
                 .build();
         AppSearchException e = assertThrows(
                 AppSearchException.class,
@@ -466,7 +483,8 @@
         InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
         mAppSearchImpl.close();
         mAppSearchImpl = AppSearchImpl.create(
-                mAppSearchDir, new UnlimitedLimitConfig(), initStatsBuilder, ALWAYS_OPTIMIZE);
+                mAppSearchDir, new UnlimitedLimitConfig(), initStatsBuilder, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
 
         // Check recovery state
         InitializeStats initStats = initStatsBuilder.build();
@@ -485,45 +503,42 @@
         assertThat(initStats.getResetStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
 
         // Make sure all our data is gone
-        assertThat(mAppSearchImpl.getSchema(context.getPackageName(), "database1").getSchemas())
+        assertThat(mAppSearchImpl.getSchema(
+                /*packageName=*/mContext.getPackageName(),
+                /*databaseName=*/"database1",
+                /*callerAccess=*/mSelfCallerAccess)
+                .getSchemas())
                 .isEmpty();
         results = mAppSearchImpl.globalQuery(
                 /*queryExpression=*/ "",
                 new SearchSpec.Builder().addFilterSchemas("Type1").build(),
-                context.getPackageName(),
-                /*visibilityStore=*/ null,
-                Process.INVALID_UID,
-                /*callerHasSystemAccess=*/ false,
+                mSelfCallerAccess,
                 /*logger=*/ null);
         assertThat(results.getResults()).isEmpty();
 
         // Make sure the index can now be used successfully
         mAppSearchImpl.setSchema(
-                context.getPackageName(),
+                mContext.getPackageName(),
                 "database1",
                 Collections.singletonList(new AppSearchSchema.Builder("Type1").build()),
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
 
         // Insert a valid doc
         mAppSearchImpl.putDocument(
-                context.getPackageName(),
+                mContext.getPackageName(),
                 "database1",
                 validDoc,
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/null);
 
         // Query it via global query.
         results = mAppSearchImpl.globalQuery(
                 /*queryExpression=*/ "",
                 new SearchSpec.Builder().addFilterSchemas("Type1").build(),
-                context.getPackageName(),
-                /*visibilityStore=*/ null,
-                Process.INVALID_UID,
-                /*callerHasSystemAccess=*/ false,
+                mSelfCallerAccess,
                 /*logger=*/ null);
         assertThat(results.getResults()).hasSize(1);
         assertThat(results.getResults().get(0).getGenericDocument()).isEqualTo(validDoc);
@@ -551,9 +566,7 @@
                 "package1",
                 "database1",
                 schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -565,9 +578,7 @@
                 "package2",
                 "database2",
                 schema2,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -575,7 +586,12 @@
         // Insert package1 document
         GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "schema1")
                 .build();
-        mAppSearchImpl.putDocument("package1", "database1", document, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // No query filters specified, package2 shouldn't be able to query for package1's documents.
         SearchSpec searchSpec =
@@ -586,7 +602,12 @@
 
         // Insert package2 document
         document = new GenericDocument.Builder<>("namespace", "id", "schema2").build();
-        mAppSearchImpl.putDocument("package2", "database2", document, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package2",
+                "database2",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // No query filters specified. package2 should only get its own documents back.
         searchResultPage = mAppSearchImpl.query("package2", "database2", "", searchSpec, /*logger=
@@ -608,9 +629,7 @@
                 "package1",
                 "database1",
                 schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -622,9 +641,7 @@
                 "package2",
                 "database2",
                 schema2,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -632,7 +649,12 @@
         // Insert package1 document
         GenericDocument document = new GenericDocument.Builder<>("namespace", "id",
                 "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // "package1" filter specified, but package2 shouldn't be able to query for package1's
         // documents.
@@ -646,7 +668,12 @@
 
         // Insert package2 document
         document = new GenericDocument.Builder<>("namespace", "id", "schema2").build();
-        mAppSearchImpl.putDocument("package2", "database2", document, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package2",
+                "database2",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // "package2" filter specified, package2 should only get its own documents back.
         searchSpec = new SearchSpec.Builder()
@@ -660,16 +687,13 @@
     }
 
     @Test
-    public void testGlobalQueryEmptyDatabase() throws Exception {
+    public void testGlobalQuery_emptyPackage() throws Exception {
         SearchSpec searchSpec =
                 new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
         SearchResultPage searchResultPage = mAppSearchImpl.globalQuery(
-                "",
+                /*queryExpression=*/"",
                 searchSpec,
-                /*callerPackageName=*/ "",
-                /*visibilityStore=*/ null,
-                Process.INVALID_UID,
-                /*callerHasSystemAccess=*/ false,
+                new CallerAccess(/*callingPackageName=*/""),
                 /*logger=*/ null);
         assertThat(searchResultPage.getResults()).isEmpty();
     }
@@ -683,9 +707,7 @@
                 "package1",
                 "database1",
                 schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -695,8 +717,18 @@
                 "schema1").build();
         GenericDocument document2 = new GenericDocument.Builder<>("namespace", "id2",
                 "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Query for only 1 result per page
         SearchSpec searchSpec = new SearchSpec.Builder()
@@ -727,9 +759,7 @@
                 "package1",
                 "database1",
                 schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -739,8 +769,18 @@
                 "schema1").build();
         GenericDocument document2 = new GenericDocument.Builder<>("namespace", "id2",
                 "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Query for only 1 result per page
         SearchSpec searchSpec = new SearchSpec.Builder()
@@ -781,9 +821,7 @@
                 "package1",
                 "database1",
                 schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -793,17 +831,29 @@
                 "schema1").build();
         GenericDocument document2 = new GenericDocument.Builder<>("namespace", "id2",
                 "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Query for only 1 result per page
         SearchSpec searchSpec = new SearchSpec.Builder()
                 .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
                 .setResultCountPerPage(1)
                 .build();
-        SearchResultPage searchResultPage = mAppSearchImpl.globalQuery(/*queryExpression=*/ "",
-                searchSpec, "package1", /*visibilityStore=*/ null, Process.myUid(),
-                /*callerHasSystemAccess=*/ false, /*logger=*/ null);
+        SearchResultPage searchResultPage = mAppSearchImpl.globalQuery(
+                /*queryExpression=*/ "",
+                searchSpec,
+                new CallerAccess(/*callingPackageName=*/"package1"),
+                /*logger=*/ null);
 
         // Document2 will come first because it was inserted last and default return order is
         // most recent.
@@ -826,9 +876,7 @@
                 "package1",
                 "database1",
                 schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -838,17 +886,29 @@
                 "schema1").build();
         GenericDocument document2 = new GenericDocument.Builder<>("namespace", "id2",
                 "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Query for only 1 result per page
         SearchSpec searchSpec = new SearchSpec.Builder()
                 .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
                 .setResultCountPerPage(1)
                 .build();
-        SearchResultPage searchResultPage = mAppSearchImpl.globalQuery(/*queryExpression=*/ "",
-                searchSpec, "package1", /*visibilityStore=*/ null, Process.myUid(),
-                /*callerHasSystemAccess=*/ false, /*logger=*/ null);
+        SearchResultPage searchResultPage = mAppSearchImpl.globalQuery(
+                /*queryExpression=*/ "",
+                searchSpec,
+                new CallerAccess(/*callingPackageName=*/"package1"),
+                /*logger=*/ null);
 
         // Document2 will come first because it was inserted last and default return order is
         // most recent.
@@ -881,9 +941,7 @@
                 "package1",
                 "database1",
                 schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -893,8 +951,18 @@
                 "schema1").build();
         GenericDocument document2 = new GenericDocument.Builder<>("namespace", "id2",
                 "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Query for only 1 result per page
         SearchSpec searchSpec = new SearchSpec.Builder()
@@ -932,9 +1000,7 @@
                 "package1",
                 "database1",
                 schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -942,7 +1008,12 @@
         // Insert one package1 documents
         GenericDocument document1 = new GenericDocument.Builder<>("namespace", "id1",
                 "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Query for 2 results per page, so all the results can fit in one page.
         SearchSpec searchSpec = new SearchSpec.Builder()
@@ -972,9 +1043,7 @@
                 "package1",
                 "database1",
                 schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -984,8 +1053,18 @@
                 "schema1").build();
         GenericDocument document2 = new GenericDocument.Builder<>("namespace", "id2",
                 "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Query for only 1 result per page
         SearchSpec searchSpec = new SearchSpec.Builder()
@@ -1026,9 +1105,7 @@
                 "package1",
                 "database1",
                 schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1038,17 +1115,29 @@
                 "schema1").build();
         GenericDocument document2 = new GenericDocument.Builder<>("namespace", "id2",
                 "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Query for only 1 result per page
         SearchSpec searchSpec = new SearchSpec.Builder()
                 .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
                 .setResultCountPerPage(1)
                 .build();
-        SearchResultPage searchResultPage = mAppSearchImpl.globalQuery(/*queryExpression=*/ "",
-                searchSpec, "package1", /*visibilityStore=*/ null, Process.myUid(),
-                /*callerHasSystemAccess=*/ false, /*logger=*/ null);
+        SearchResultPage searchResultPage = mAppSearchImpl.globalQuery(
+                /*queryExpression=*/ "",
+                searchSpec,
+                new CallerAccess(/*callingPackageName=*/"package1"),
+                /*logger=*/ null);
 
         // Document2 will come first because it was inserted last and default return order is
         // most recent.
@@ -1078,9 +1167,7 @@
                 "package1",
                 "database1",
                 schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1090,17 +1177,29 @@
                 "schema1").build();
         GenericDocument document2 = new GenericDocument.Builder<>("namespace", "id2",
                 "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Query for only 1 result per page
         SearchSpec searchSpec = new SearchSpec.Builder()
                 .setTermMatch(TermMatchType.Code.PREFIX_VALUE)
                 .setResultCountPerPage(1)
                 .build();
-        SearchResultPage searchResultPage = mAppSearchImpl.globalQuery(/*queryExpression=*/ "",
-                searchSpec, "package1", /*visibilityStore=*/ null, Process.myUid(),
-                /*callerHasSystemAccess=*/ false, /*logger=*/ null);
+        SearchResultPage searchResultPage = mAppSearchImpl.globalQuery(
+                /*queryExpression=*/ "",
+                searchSpec,
+                new CallerAccess(/*callingPackageName=*/"package1"),
+                /*logger=*/ null);
 
         // Document2 will come first because it was inserted last and default return order is
         // most recent.
@@ -1155,9 +1254,7 @@
                 "package",
                 "database1",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1193,9 +1290,7 @@
                 "package",
                 "database1",
                 oldSchemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1209,9 +1304,7 @@
                 "package",
                 "database1",
                 newSchemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ true,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1232,9 +1325,7 @@
                 "package",
                 "database1",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1262,9 +1353,7 @@
                         "package",
                         "database1",
                         finalSchemas,
-                        /*visibilityStore=*/ null,
-                        /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                        /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                        /*visibilityDocuments=*/ Collections.emptyList(),
                         /*forceOverride=*/ false,
                         /*version=*/ 0,
                         /* setSchemaStatsBuilder= */ null);
@@ -1276,9 +1365,7 @@
                 "package",
                 "database1",
                 finalSchemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ true,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1312,9 +1399,7 @@
                 "package",
                 "database1",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1322,9 +1407,7 @@
                 "package",
                 "database2",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1356,9 +1439,7 @@
                 "package",
                 "database1",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ true,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1397,9 +1478,7 @@
                 "package",
                 "database",
                 schema,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1407,7 +1486,11 @@
         // Insert package document
         GenericDocument document = new GenericDocument.Builder<>("namespace", "id",
                 "schema").build();
-        mAppSearchImpl.putDocument("package", "database", document,
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document,
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
 
         // Verify the document is indexed.
@@ -1444,6 +1527,13 @@
             existingPackages.add(PrefixUtil.getPackageName(existingSchemas.get(i).getSchemaType()));
         }
 
+        // Create VisibilityDocument
+        VisibilityDocument visibilityDocument = new VisibilityDocument.Builder("schema")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .setCreationTimestampMillis(12345L)
+                .build();
+
         // Insert schema for package A and B.
         List<AppSearchSchema> schema =
                 ImmutableList.of(new AppSearchSchema.Builder("schema").build());
@@ -1451,9 +1541,7 @@
                 "packageA",
                 "database",
                 schema,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ ImmutableList.of(visibilityDocument),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1461,14 +1549,12 @@
                 "packageB",
                 "database",
                 schema,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ ImmutableList.of(visibilityDocument),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
 
-        // Verify these two packages is stored in AppSearch
+        // Verify these two packages are stored in AppSearch.
         SchemaProto expectedProto = SchemaProto.newBuilder()
                 .addTypes(
                         SchemaTypeConfigProto.newBuilder()
@@ -1483,6 +1569,26 @@
         assertThat(mAppSearchImpl.getSchemaProtoLocked().getTypesList())
                 .containsExactlyElementsIn(expectedTypes);
 
+        // Verify these two visibility documents are stored in AppSearch.
+        VisibilityDocument expectedVisibilityDocumentA =
+                new VisibilityDocument.Builder("packageA$database/schema")
+                        .setNotDisplayedBySystem(true)
+                        .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                        .setCreationTimestampMillis(12345L)
+                        .build();
+        VisibilityDocument expectedVisibilityDocumentB =
+                new VisibilityDocument.Builder("packageB$database/schema")
+                        .setNotDisplayedBySystem(true)
+                        .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                        .setCreationTimestampMillis(12345L)
+                        .build();
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked
+                .getVisibility("packageA$database/schema"))
+                .isEqualTo(expectedVisibilityDocumentA);
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked
+                .getVisibility("packageB$database/schema"))
+                .isEqualTo(expectedVisibilityDocumentB);
+
         // Prune packages
         mAppSearchImpl.prunePackageData(existingPackages);
 
@@ -1491,6 +1597,12 @@
                 .containsExactlyElementsIn(existingSchemas);
         assertThat(mAppSearchImpl.getPackageToDatabases())
                 .containsExactlyEntriesIn(existingDatabases);
+
+        // Verify the VisibilitySetting is removed.
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked
+                .getVisibility("packageA$database/schema")).isNull();
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked
+                .getVisibility("packageB$database/schema")).isNull();
     }
 
     @Test
@@ -1504,9 +1616,7 @@
         mAppSearchImpl.setSchema(
                 "package1", "database1",
                 Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1518,9 +1628,7 @@
         mAppSearchImpl.setSchema(
                 "package1", "database2",
                 Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1532,9 +1640,7 @@
         mAppSearchImpl.setSchema(
                 "package2", "database1",
                 Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1542,6 +1648,47 @@
                 expectedMapping);
     }
 
+    @Test
+    public void testGetAllPrefixedSchemaTypes() throws Exception {
+        // Insert schema
+        List<AppSearchSchema> schemas1 =
+                Collections.singletonList(new AppSearchSchema.Builder("type1").build());
+        List<AppSearchSchema> schemas2 =
+                Collections.singletonList(new AppSearchSchema.Builder("type2").build());
+        List<AppSearchSchema> schemas3 =
+                Collections.singletonList(new AppSearchSchema.Builder("type3").build());
+        mAppSearchImpl.setSchema(
+                "package1",
+                "database1",
+                schemas1,
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+        mAppSearchImpl.setSchema(
+                "package1",
+                "database2",
+                schemas2,
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+        mAppSearchImpl.setSchema(
+                "package2",
+                "database1",
+                schemas3,
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+        assertThat(mAppSearchImpl.getAllPrefixedSchemaTypes()).containsExactly(
+                "package1$database1/type1",
+                "package1$database2/type2",
+                "package2$database1/type3",
+                "VS#Pkg$VS#Db/VisibilityType",  // plus the stored Visibility schema
+                "VS#Pkg$VS#Db/VisibilityPermissionType");
+    }
+
     @FlakyTest(bugId = 204186664)
     @Test
     public void testReportUsage() throws Exception {
@@ -1552,9 +1699,7 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1564,8 +1709,18 @@
                 new GenericDocument.Builder<>("namespace", "id1", "type").build();
         GenericDocument document2 =
                 new GenericDocument.Builder<>("namespace", "id2", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package", "database", document2, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Report some usages. id1 has 2 app and 1 system usage, id2 has 1 app and 2 system usage.
         mAppSearchImpl.reportUsage("package", "database", "namespace",
@@ -1642,9 +1797,7 @@
                 "package1",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1666,9 +1819,7 @@
                 "package1",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1676,25 +1827,38 @@
         // Insert document for "package1"
         GenericDocument document =
                 new GenericDocument.Builder<>("namespace", "id1", "type").build();
-        mAppSearchImpl.putDocument("package1", "database", document, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Insert schema for "package2"
         mAppSearchImpl.setSchema(
                 "package2",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
 
         // Insert two documents for "package2"
         document = new GenericDocument.Builder<>("namespace", "id1", "type").build();
-        mAppSearchImpl.putDocument("package2", "database", document, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package2",
+                "database",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
         document = new GenericDocument.Builder<>("namespace", "id2", "type").build();
-        mAppSearchImpl.putDocument("package2", "database", document, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package2",
+                "database",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForPackage("package1");
         long size1 = storageInfo.getSizeBytes();
@@ -1732,9 +1896,7 @@
                 "package1",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1756,9 +1918,7 @@
                 "package1",
                 "database1",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1779,9 +1939,7 @@
                 "package1",
                 "database1",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1789,9 +1947,7 @@
                 "package1",
                 "database2",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1799,14 +1955,28 @@
         // Add a document for "package1", "database1"
         GenericDocument document =
                 new GenericDocument.Builder<>("namespace1", "id1", "type").build();
-        mAppSearchImpl.putDocument("package1", "database1", document, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Add two documents for "package1", "database2"
         document = new GenericDocument.Builder<>("namespace1", "id1", "type").build();
-        mAppSearchImpl.putDocument("package1", "database2", document, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database2",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
         document = new GenericDocument.Builder<>("namespace1", "id2", "type").build();
-        mAppSearchImpl.putDocument("package1", "database2", document, /*logger=*/ null);
-
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database2",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         StorageInfo storageInfo = mAppSearchImpl.getStorageInfoForDatabase("package1", "database1");
         long size1 = storageInfo.getSizeBytes();
@@ -1834,9 +2004,7 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1848,20 +2016,21 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null));
 
         assertThrows(IllegalStateException.class, () -> mAppSearchImpl.getSchema(
-                "package", "database"));
+                /*packageName=*/"package",
+                /*databaseName=*/"database",
+                /*callerAccess=*/mSelfCallerAccess));
 
         assertThrows(IllegalStateException.class, () -> mAppSearchImpl.putDocument(
                 "package",
                 "database",
                 new GenericDocument.Builder<>("namespace", "id", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null));
 
         assertThrows(IllegalStateException.class, () -> mAppSearchImpl.getDocument(
@@ -1877,10 +2046,7 @@
         assertThrows(IllegalStateException.class, () -> mAppSearchImpl.globalQuery(
                 "query",
                 new SearchSpec.Builder().build(),
-                "package",
-                /*visibilityStore=*/ null,
-                Process.INVALID_UID,
-                /*callerHasSystemAccess=*/ false,
+                mSelfCallerAccess,
                 /*logger=*/ null));
 
         assertThrows(IllegalStateException.class, () -> mAppSearchImpl.getNextPage("package",
@@ -1922,9 +2088,7 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1932,7 +2096,12 @@
         // Add a document and persist it.
         GenericDocument document =
                 new GenericDocument.Builder<>("namespace1", "id1", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document, /*logger=*/null);
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
         mAppSearchImpl.persistToDisk(PersistType.Code.LITE);
 
         GenericDocument getResult = mAppSearchImpl.getDocument("package", "database", "namespace1",
@@ -1945,7 +2114,8 @@
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
                 /*initStatsBuilder=*/ null,
-                ALWAYS_OPTIMIZE);
+                ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
         getResult = appSearchImpl2.getDocument("package", "database", "namespace1",
                 "id1",
                 Collections.emptyMap());
@@ -1961,9 +2131,7 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -1971,10 +2139,20 @@
         // Add two documents and persist them.
         GenericDocument document1 =
                 new GenericDocument.Builder<>("namespace1", "id1", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document1, /*logger=*/null);
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
         GenericDocument document2 =
                 new GenericDocument.Builder<>("namespace1", "id2", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document2, /*logger=*/null);
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
         mAppSearchImpl.persistToDisk(PersistType.Code.LITE);
 
         GenericDocument getResult = mAppSearchImpl.getDocument("package", "database", "namespace1",
@@ -2004,7 +2182,8 @@
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
                 /*initStatsBuilder=*/ null,
-                ALWAYS_OPTIMIZE);
+                ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
         assertThrows(AppSearchException.class, () -> appSearchImpl2.getDocument("package",
                 "database",
                 "namespace1",
@@ -2025,9 +2204,7 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -2035,10 +2212,20 @@
         // Add two documents and persist them.
         GenericDocument document1 =
                 new GenericDocument.Builder<>("namespace1", "id1", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document1, /*logger=*/null);
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
         GenericDocument document2 =
                 new GenericDocument.Builder<>("namespace2", "id2", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document2, /*logger=*/null);
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
         mAppSearchImpl.persistToDisk(PersistType.Code.LITE);
 
         GenericDocument getResult = mAppSearchImpl.getDocument("package", "database", "namespace1",
@@ -2070,7 +2257,8 @@
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
                 /*initStatsBuilder=*/ null,
-                ALWAYS_OPTIMIZE);
+                ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
         assertThrows(AppSearchException.class, () -> appSearchImpl2.getDocument("package",
                 "database",
                 "namespace1",
@@ -2091,9 +2279,7 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -2101,10 +2287,20 @@
         // Add two documents
         GenericDocument document1 =
                 new GenericDocument.Builder<>("namespace1", "id1", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document1, /*logger=*/null);
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
         GenericDocument document2 =
                 new GenericDocument.Builder<>("namespace1", "id2", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document2, /*logger=*/null);
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         StorageInfoProto storageInfo = mAppSearchImpl.getRawStorageInfoProto();
 
@@ -2116,7 +2312,7 @@
                 .isEqualTo(2);
         assertThat(
                 storageInfo.getSchemaStoreStorageInfo().getNumSchemaTypes())
-                .isEqualTo(1);
+                .isEqualTo(3); // +2 for VisibilitySchema
     }
 
     @Test
@@ -2136,7 +2332,8 @@
                         return 1;
                     }
                 },
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
 
         // Insert schema
         List<AppSearchSchema> schemas =
@@ -2145,9 +2342,7 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -2156,7 +2351,12 @@
         GenericDocument document = new GenericDocument.Builder<>(
                 "this_namespace_is_long_to_make_the_doc_big", "id", "type").build();
         AppSearchException e = assertThrows(AppSearchException.class, () ->
-                mAppSearchImpl.putDocument("package", "database", document, /*logger=*/ null));
+                mAppSearchImpl.putDocument(
+                        "package",
+                        "database",
+                        document,
+                        /*sendChangeNotifications=*/ false,
+                        /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
                 "Document \"id\" for package \"package\" serialized to 99 bytes, which exceeds"
@@ -2166,13 +2366,23 @@
         // index 1 document.
         GenericDocument document2 =
                 new GenericDocument.Builder<>("namespace", "id2", "type").build();
-        mAppSearchImpl.putDocument("package", "database", document2, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Now we should get a failure
         GenericDocument document3 =
                 new GenericDocument.Builder<>("namespace", "id3", "type").build();
         e = assertThrows(AppSearchException.class, () ->
-                mAppSearchImpl.putDocument("package", "database", document3, /*logger=*/ null));
+                mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document3,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
                 "Package \"package\" exceeded limit of 1 documents");
@@ -2196,7 +2406,8 @@
                         return 1;
                     }
                 },
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
 
         // Insert schema
         List<AppSearchSchema> schemas =
@@ -2205,9 +2416,7 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -2217,13 +2426,19 @@
                 "package",
                 "database",
                 new GenericDocument.Builder<>("namespace", "id1", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
 
         // Now we should get a failure
         GenericDocument document2 =
                 new GenericDocument.Builder<>("namespace", "id2", "type").build();
         AppSearchException e = assertThrows(AppSearchException.class, () ->
-                mAppSearchImpl.putDocument("package", "database", document2, /*logger=*/ null));
+                mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
                 "Package \"package\" exceeded limit of 1 documents");
@@ -2243,11 +2458,17 @@
                         return 1;
                     }
                 },
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
 
         // Make sure the limit is maintained
         e = assertThrows(AppSearchException.class, () ->
-                mAppSearchImpl.putDocument("package", "database", document2, /*logger=*/ null));
+                mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
                 "Package \"package\" exceeded limit of 1 documents");
@@ -2270,7 +2491,8 @@
                         return 3;
                     }
                 },
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
 
         // Insert schema
         List<AppSearchSchema> schemas =
@@ -2279,9 +2501,7 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -2291,23 +2511,31 @@
                 "package",
                 "database",
                 new GenericDocument.Builder<>("namespace", "id1", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
         mAppSearchImpl.putDocument(
                 "package",
                 "database",
                 new GenericDocument.Builder<>("namespace", "id2", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
         mAppSearchImpl.putDocument(
                 "package",
                 "database",
                 new GenericDocument.Builder<>("namespace", "id3", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
 
         // Now we should get a failure
         GenericDocument document4 =
                 new GenericDocument.Builder<>("namespace", "id4", "type").build();
         AppSearchException e = assertThrows(AppSearchException.class, () ->
-                mAppSearchImpl.putDocument("package", "database", document4, /*logger=*/ null));
+                mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document4,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
                 "Package \"package\" exceeded limit of 3 documents");
@@ -2319,7 +2547,12 @@
 
         // Should still fail
         e = assertThrows(AppSearchException.class, () ->
-                mAppSearchImpl.putDocument("package", "database", document4, /*logger=*/ null));
+                mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document4,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
                 "Package \"package\" exceeded limit of 3 documents");
@@ -2329,13 +2562,19 @@
                 "package", "database", "namespace", "id2", /*removeStatsBuilder=*/null);
 
         // Now doc4 should work
-        mAppSearchImpl.putDocument("package", "database", document4, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document4,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // The next one should fail again
         e = assertThrows(AppSearchException.class, () -> mAppSearchImpl.putDocument(
                 "package",
                 "database",
                 new GenericDocument.Builder<>("namespace", "id5", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
@@ -2360,7 +2599,8 @@
                         return 2;
                     }
                 },
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
 
         // Insert schema
         List<AppSearchSchema> schemas =
@@ -2369,9 +2609,7 @@
                 "package1",
                 "database1",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -2379,9 +2617,7 @@
                 "package1",
                 "database2",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -2389,9 +2625,7 @@
                 "package2",
                 "database1",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -2399,9 +2633,7 @@
                 "package2",
                 "database2",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -2411,11 +2643,13 @@
                 "package1",
                 "database1",
                 new GenericDocument.Builder<>("namespace", "id1", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
         mAppSearchImpl.putDocument(
                 "package1",
                 "database2",
                 new GenericDocument.Builder<>("namespace", "id2", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
 
         // Indexing a third doc into package1 should fail (here we use database3)
@@ -2424,6 +2658,7 @@
                         "package1",
                         "database3",
                         new GenericDocument.Builder<>("namespace", "id3", "type").build(),
+                        /*sendChangeNotifications=*/ false,
                         /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
@@ -2434,6 +2669,7 @@
                 "package2",
                 "database1",
                 new GenericDocument.Builder<>("namespace", "id1", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
 
         // Reinitialize to make sure packages are parsed correctly on init
@@ -2451,7 +2687,8 @@
                         return 2;
                     }
                 },
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
 
         // package1 should still be out of space
         e = assertThrows(AppSearchException.class, () ->
@@ -2459,6 +2696,7 @@
                         "package1",
                         "database4",
                         new GenericDocument.Builder<>("namespace", "id4", "type").build(),
+                        /*sendChangeNotifications=*/ false,
                         /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
@@ -2469,6 +2707,7 @@
                 "package2",
                 "database2",
                 new GenericDocument.Builder<>("namespace", "id2", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
 
         // now package2 really is out of space
@@ -2477,6 +2716,7 @@
                         "package2",
                         "database3",
                         new GenericDocument.Builder<>("namespace", "id3", "type").build(),
+                        /*sendChangeNotifications=*/ false,
                         /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
@@ -2500,7 +2740,8 @@
                         return 3;
                     }
                 },
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
 
         // Insert schema
         List<AppSearchSchema> schemas = Collections.singletonList(
@@ -2516,9 +2757,7 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -2530,6 +2769,7 @@
                 new GenericDocument.Builder<>("namespace", "id1", "type")
                         .setPropertyString("body", "tablet")
                         .build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
         mAppSearchImpl.putDocument(
                 "package",
@@ -2537,6 +2777,7 @@
                 new GenericDocument.Builder<>("namespace", "id2", "type")
                         .setPropertyString("body", "tabby")
                         .build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
         mAppSearchImpl.putDocument(
                 "package",
@@ -2544,13 +2785,19 @@
                 new GenericDocument.Builder<>("namespace", "id3", "type")
                         .setPropertyString("body", "grabby")
                         .build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
 
         // Now we should get a failure
         GenericDocument document4 =
                 new GenericDocument.Builder<>("namespace", "id4", "type").build();
         AppSearchException e = assertThrows(AppSearchException.class, () ->
-                mAppSearchImpl.putDocument("package", "database", document4, /*logger=*/ null));
+                mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document4,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
                 "Package \"package\" exceeded limit of 3 documents");
@@ -2565,7 +2812,12 @@
 
         // Should still fail
         e = assertThrows(AppSearchException.class, () ->
-                mAppSearchImpl.putDocument("package", "database", document4, /*logger=*/ null));
+                mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document4,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
                 "Package \"package\" exceeded limit of 3 documents");
@@ -2579,11 +2831,17 @@
                 /*removeStatsBuilder=*/null);
 
         // Now doc4 and doc5 should work
-        mAppSearchImpl.putDocument("package", "database", document4, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document4,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
         mAppSearchImpl.putDocument(
                 "package",
                 "database",
                 new GenericDocument.Builder<>("namespace", "id5", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
 
         // We only deleted 2 docs so the next one should fail again
@@ -2591,6 +2849,7 @@
                 "package",
                 "database",
                 new GenericDocument.Builder<>("namespace", "id6", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
@@ -2614,7 +2873,8 @@
                         return 2;
                     }
                 },
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
 
         // Insert schema
         List<AppSearchSchema> schemas = Collections.singletonList(
@@ -2626,9 +2886,7 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -2640,6 +2898,7 @@
                 new GenericDocument.Builder<>("namespace", "id1", "type")
                         .setPropertyString("body", "id1.orig")
                         .build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
         // Replace it with another doc
         mAppSearchImpl.putDocument(
@@ -2648,6 +2907,7 @@
                 new GenericDocument.Builder<>("namespace", "id1", "type")
                         .setPropertyString("body", "id1.new")
                         .build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
 
         // Index id2. This should pass but only because we check for replacements.
@@ -2655,13 +2915,19 @@
                 "package",
                 "database",
                 new GenericDocument.Builder<>("namespace", "id2", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
 
         // Now we should get a failure on id3
         GenericDocument document3 =
                 new GenericDocument.Builder<>("namespace", "id3", "type").build();
         AppSearchException e = assertThrows(AppSearchException.class, () ->
-                mAppSearchImpl.putDocument("package", "database", document3, /*logger=*/ null));
+                mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document3,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
                 "Package \"package\" exceeded limit of 2 documents");
@@ -2685,7 +2951,8 @@
                         return 2;
                     }
                 },
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
 
         // Insert schema
         List<AppSearchSchema> schemas = Collections.singletonList(
@@ -2697,9 +2964,7 @@
                 "package",
                 "database",
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -2711,6 +2976,7 @@
                 new GenericDocument.Builder<>("namespace", "id1", "type")
                         .setPropertyString("body", "id1.orig")
                         .build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
         // Replace it with another doc
         mAppSearchImpl.putDocument(
@@ -2719,6 +2985,7 @@
                 new GenericDocument.Builder<>("namespace", "id1", "type")
                         .setPropertyString("body", "id1.new")
                         .build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
 
         // Reinitialize to make sure replacements are correctly accounted for by init
@@ -2736,22 +3003,1796 @@
                         return 2;
                     }
                 },
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
 
         // Index id2. This should pass but only because we check for replacements.
         mAppSearchImpl.putDocument(
                 "package",
                 "database",
                 new GenericDocument.Builder<>("namespace", "id2", "type").build(),
+                /*sendChangeNotifications=*/ false,
                 /*logger=*/ null);
 
         // Now we should get a failure on id3
         GenericDocument document3 =
                 new GenericDocument.Builder<>("namespace", "id3", "type").build();
         AppSearchException e = assertThrows(AppSearchException.class, () ->
-                mAppSearchImpl.putDocument("package", "database", document3, /*logger=*/ null));
+                mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document3,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null));
         assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_OUT_OF_SPACE);
         assertThat(e).hasMessageThat().contains(
                 "Package \"package\" exceeded limit of 2 documents");
     }
+
+    /**
+     * Ensure that it is okay to register the same observer for multiple packages and that removing
+     * the observer for one package doesn't remove it for the other.
+     */
+    @Test
+    public void testRemoveObserver_onlyAffectsOnePackage() throws Exception {
+        final String fakePackage = "com.android.appsearch.fake.package";
+
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                /*schemas=*/ImmutableList.of(new AppSearchSchema.Builder("Type1").build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/false,
+                /*version=*/0,
+                /*setSchemaStatsBuilder=*/null);
+
+        // Register an observer twice, on different packages.
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                /*listeningPackageAccess=*/mSelfCallerAccess,
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+        mAppSearchImpl.registerObserverCallback(
+                /*listeningPackageAccess=*/mSelfCallerAccess,
+                /*targetPackageName=*/fakePackage,
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Insert a valid doc
+        GenericDocument validDoc =
+                new GenericDocument.Builder<>("namespace1", "id1", "Type1").build();
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.putDocument(
+                mContext.getPackageName(),
+                "database1",
+                validDoc,
+                /*sendChangeNotifications=*/ true,
+                /*logger=*/null);
+
+        // Dispatch notifications and empty the observers
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        observer.clear();
+
+        // Remove the observer from the fake package
+        mAppSearchImpl.unregisterObserverCallback(fakePackage, observer);
+
+        // Index a second document
+        GenericDocument doc2 = new GenericDocument.Builder<>("namespace1", "id2", "Type1").build();
+        mAppSearchImpl.putDocument(
+                mContext.getPackageName(),
+                "database1",
+                doc2,
+                /*sendChangeNotifications=*/ true,
+                /*logger=*/null);
+
+        // Observer should still have received this data from its registration on
+        // context.getPackageName(), as we only removed the copy from fakePackage.
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).containsExactly(
+                new DocumentChangeInfo(
+                        mContext.getPackageName(),
+                        "database1",
+                        "namespace1",
+                        "Type1",
+                        /*changedDocumentIds=*/ImmutableSet.of("id2")));
+    }
+
+    @Test
+    public void testGetGlobalDocumentThrowsExceptionWhenNotVisible() throws Exception {
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("type").build());
+
+        // Create a new mAppSearchImpl with a mock Visibility Checker
+        mAppSearchImpl.close();
+        File tempFolder = mTemporaryFolder.newFolder();
+        VisibilityChecker mockVisibilityChecker =
+                (callerAccess, packageName, prefixedSchema, visibilityStore) -> false;
+        mAppSearchImpl = AppSearchImpl.create(
+                tempFolder,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/ null,
+                ALWAYS_OPTIMIZE,
+                mockVisibilityChecker);
+
+        mAppSearchImpl.setSchema(
+                "package",
+                "database",
+                schemas,
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+
+        // Add a document and persist it.
+        GenericDocument document =
+                new GenericDocument.Builder<>("namespace1", "id1", "type").build();
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document,
+                /*sendChangeNotifications=*/false,
+                /*logger=*/null);
+        mAppSearchImpl.persistToDisk(PersistType.Code.LITE);
+
+        AppSearchException e = assertThrows(AppSearchException.class, () ->
+                mAppSearchImpl.globalGetDocument(
+                        "package",
+                        "database",
+                        "namespace1",
+                        "id1",
+                        /*typePropertyPaths=*/Collections.emptyMap(),
+                        /*callerAccess=*/mSelfCallerAccess));
+        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
+        assertThat(e.getMessage()).isEqualTo("Document (namespace1, id1) not found.");
+    }
+
+    @Test
+    public void testGetGlobalDocument() throws Exception {
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("type").build());
+
+        // Create a new mAppSearchImpl with a mock Visibility Checker
+        mAppSearchImpl.close();
+        File tempFolder = mTemporaryFolder.newFolder();
+        VisibilityChecker mockVisibilityChecker =
+                (callerAccess, packageName, prefixedSchema, visibilityStore) -> true;
+        mAppSearchImpl = AppSearchImpl.create(
+                tempFolder,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/ null,
+                ALWAYS_OPTIMIZE,
+                mockVisibilityChecker);
+
+        mAppSearchImpl.setSchema(
+                "package",
+                "database",
+                schemas,
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+
+        // Add a document and persist it.
+        GenericDocument document =
+                new GenericDocument.Builder<>("namespace1", "id1", "type").build();
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.persistToDisk(PersistType.Code.LITE);
+
+        GenericDocument getResult = mAppSearchImpl.globalGetDocument(
+                "package",
+                "database",
+                "namespace1",
+                "id1",
+                /*typePropertyPaths=*/Collections.emptyMap(),
+                /*callerAccess=*/mSelfCallerAccess);
+        assertThat(getResult).isEqualTo(document);
+    }
+
+    @Test
+    public void getGlobalDocumentTest_notFound() throws Exception {
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("type").build());
+
+        // Create a new mAppSearchImpl with a mock Visibility Checker
+        mAppSearchImpl.close();
+        File tempFolder = mTemporaryFolder.newFolder();
+        VisibilityChecker mockVisibilityChecker =
+                (callerAccess, packageName, prefixedSchema, visibilityStore) -> true;
+        mAppSearchImpl = AppSearchImpl.create(
+                tempFolder,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/ null,
+                ALWAYS_OPTIMIZE,
+                mockVisibilityChecker);
+
+        mAppSearchImpl.setSchema(
+                "package",
+                "database",
+                schemas,
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+
+        // Add a document and persist it.
+        GenericDocument document =
+                new GenericDocument.Builder<>("namespace1", "id1", "type").build();
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.persistToDisk(PersistType.Code.LITE);
+
+        AppSearchException e = assertThrows(AppSearchException.class, () ->
+                mAppSearchImpl.globalGetDocument(
+                        "package",
+                        "database",
+                        "namespace1",
+                        "id2",
+                        /*typePropertyPaths=*/Collections.emptyMap(),
+                        /*callerAccess=*/mSelfCallerAccess));
+        assertThat(e.getResultCode()).isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
+        assertThat(e.getMessage()).isEqualTo("Document (namespace1, id2) not found.");
+    }
+
+    @Test
+    public void getGlobalDocumentNoAccessNoFileHasSameException() throws Exception {
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("type").build());
+        // Create a new mAppSearchImpl with a mock Visibility Checker
+        mAppSearchImpl.close();
+        File tempFolder = mTemporaryFolder.newFolder();
+        VisibilityChecker mockVisibilityChecker =
+                (callerAccess, packageName, prefixedSchema, visibilityStore) ->
+                        callerAccess.getCallingPackageName().equals("visiblePackage");
+        mAppSearchImpl = AppSearchImpl.create(
+                tempFolder,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/ null,
+                ALWAYS_OPTIMIZE,
+                mockVisibilityChecker);
+
+        mAppSearchImpl.setSchema(
+                "package",
+                "database",
+                schemas,
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+
+        // Add a document and persist it.
+        GenericDocument document =
+                new GenericDocument.Builder<>("namespace1", "id1", "type").build();
+        mAppSearchImpl.putDocument(
+                "package",
+                "database",
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.persistToDisk(PersistType.Code.LITE);
+
+        AppSearchException unauthorizedException = assertThrows(AppSearchException.class, () ->
+                mAppSearchImpl.globalGetDocument(
+                        "package",
+                        "database",
+                        "namespace1",
+                        "id1",
+                        /*typePropertyPaths=*/Collections.emptyMap(),
+                        new CallerAccess(/*callingPackageName=*/"invisiblePackage")));
+
+        mAppSearchImpl.remove("package", "database", "namespace1", "id1",
+                /*removeStatsBuilder=*/null);
+
+        AppSearchException noDocException = assertThrows(AppSearchException.class, () ->
+                mAppSearchImpl.globalGetDocument(
+                        "package",
+                        "database",
+                        "namespace1",
+                        "id1",
+                        /*typePropertyPaths=*/Collections.emptyMap(),
+                        new CallerAccess(/*callingPackageName=*/"visiblePackage")));
+
+        assertThat(noDocException.getResultCode()).isEqualTo(unauthorizedException.getResultCode());
+        assertThat(noDocException.getMessage()).isEqualTo(unauthorizedException.getMessage());
+    }
+
+    @Test
+    public void testSetVisibility() throws Exception {
+        VisibilityDocument visibilityDocument = new VisibilityDocument.Builder("Email")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .setCreationTimestampMillis(12345L)
+                .build();
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("Email").build());
+
+        // Set schema Email to AppSearch database1 with a visibility document
+        mAppSearchImpl.setSchema(
+                "package",
+                "database1",
+                schemas,
+                /*visibilityDocuments=*/ ImmutableList.of(visibilityDocument),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+        String prefix = PrefixUtil.createPrefix("package", "database1");
+
+        // assert the visibility document is saved.
+        VisibilityDocument expectedDocument = new VisibilityDocument.Builder(prefix + "Email")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .setCreationTimestampMillis(12345L)
+                .build();
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix + "Email"))
+                .isEqualTo(expectedDocument);
+        // Verify the VisibilityDocument is saved to AppSearchImpl.
+        VisibilityDocument actualDocument =  new VisibilityDocument(mAppSearchImpl.getDocument(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                VisibilityDocument.NAMESPACE,
+                /*id=*/ prefix + "Email",
+                /*typePropertyPaths=*/ Collections.emptyMap()));
+        assertThat(actualDocument).isEqualTo(expectedDocument);
+    }
+
+    @Test
+    public void testSetVisibility_existingVisibilitySettingRetains() throws Exception {
+        // Create Visibility Document for Email1
+        VisibilityDocument visibilityDocument1 = new VisibilityDocument.Builder("Email1")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .setCreationTimestampMillis(12345L)
+                .build();
+        List<AppSearchSchema> schemas1 =
+                Collections.singletonList(new AppSearchSchema.Builder("Email1").build());
+
+        // Set schema Email1 to package1 with a visibility document
+        mAppSearchImpl.setSchema(
+                "package1",
+                "database",
+                schemas1,
+                /*visibilityDocuments=*/ ImmutableList.of(visibilityDocument1),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+        String prefix1 = PrefixUtil.createPrefix("package1", "database");
+
+        // assert the visibility document is saved.
+        VisibilityDocument expectedDocument1 = new VisibilityDocument.Builder(prefix1 + "Email1")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .setCreationTimestampMillis(12345L)
+                .build();
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix1 + "Email1"))
+                .isEqualTo(expectedDocument1);
+        // Verify the VisibilityDocument is saved to AppSearchImpl.
+        VisibilityDocument actualDocument1 =  new VisibilityDocument(mAppSearchImpl.getDocument(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                VisibilityDocument.NAMESPACE,
+                /*id=*/ prefix1 + "Email1",
+                /*typePropertyPaths=*/ Collections.emptyMap()));
+        assertThat(actualDocument1).isEqualTo(expectedDocument1);
+
+        // Create Visibility Document for Email2
+        VisibilityDocument visibilityDocument2 = new VisibilityDocument.Builder("Email2")
+                .setNotDisplayedBySystem(false)
+                .addVisibleToPackage(new PackageIdentifier("pkgFoo", new byte[32]))
+                .setCreationTimestampMillis(54321L)
+                .build();
+        List<AppSearchSchema> schemas2 =
+                Collections.singletonList(new AppSearchSchema.Builder("Email2").build());
+
+        // Set schema Email2 to package1 with a visibility document
+        mAppSearchImpl.setSchema(
+                "package2",
+                "database",
+                schemas2,
+                /*visibilityDocuments=*/ ImmutableList.of(visibilityDocument2),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+        String prefix2 = PrefixUtil.createPrefix("package2", "database");
+
+        // assert the visibility document is saved.
+        VisibilityDocument expectedDocument2 = new VisibilityDocument.Builder(prefix2 + "Email2")
+                .setNotDisplayedBySystem(false)
+                .addVisibleToPackage(new PackageIdentifier("pkgFoo", new byte[32]))
+                .setCreationTimestampMillis(54321)
+                .build();
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix2 + "Email2"))
+                .isEqualTo(expectedDocument2);
+        // Verify the VisibilityDocument is saved to AppSearchImpl.
+        VisibilityDocument actualDocument2 =  new VisibilityDocument(mAppSearchImpl.getDocument(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                VisibilityDocument.NAMESPACE,
+                /*id=*/ prefix2 + "Email2",
+                /*typePropertyPaths=*/ Collections.emptyMap()));
+        assertThat(actualDocument2).isEqualTo(expectedDocument2);
+
+        // Check the existing visibility document retains.
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix1 + "Email1"))
+                .isEqualTo(expectedDocument1);
+        // Verify the VisibilityDocument is saved to AppSearchImpl.
+        actualDocument1 =  new VisibilityDocument(mAppSearchImpl.getDocument(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                VisibilityDocument.NAMESPACE,
+                /*id=*/ prefix1 + "Email1",
+                /*typePropertyPaths=*/ Collections.emptyMap()));
+        assertThat(actualDocument1).isEqualTo(expectedDocument1);
+    }
+
+    @Test
+    public void testSetVisibility_removeVisibilitySettings() throws Exception {
+        // Create a non-all-default visibility document
+        VisibilityDocument visibilityDocument = new VisibilityDocument.Builder("Email")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .setCreationTimestampMillis(12345L)
+                .build();
+
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("Email").build());
+
+        // Set schema Email and its visibility document to AppSearch database1
+        mAppSearchImpl.setSchema(
+                "package",
+                "database1",
+                schemas,
+                /*visibilityDocuments=*/ ImmutableList.of(visibilityDocument),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+        String prefix = PrefixUtil.createPrefix("package", "database1");
+        VisibilityDocument expectedDocument = new VisibilityDocument.Builder(prefix + "Email")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .setCreationTimestampMillis(12345L)
+                .build();
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix + "Email"))
+                .isEqualTo(expectedDocument);
+        // Verify the VisibilityDocument is saved to AppSearchImpl.
+        VisibilityDocument actualDocument =  new VisibilityDocument(mAppSearchImpl.getDocument(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                VisibilityDocument.NAMESPACE,
+                /*id=*/ prefix + "Email",
+                /*typePropertyPaths=*/ Collections.emptyMap()));
+        assertThat(actualDocument).isEqualTo(expectedDocument);
+
+        // Set schema Email and its all-default visibility document to AppSearch database1
+        mAppSearchImpl.setSchema(
+                "package",
+                "database1",
+                schemas,
+                /*visibilityDocuments=*/ ImmutableList.of(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+        // All-default visibility document won't be saved in AppSearch.
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix + "Email"))
+                .isNull();
+        // Verify the VisibilityDocument is removed from AppSearchImpl.
+        AppSearchException e = assertThrows(AppSearchException.class,
+                () -> mAppSearchImpl.getDocument(
+                        VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                        VisibilityStore.VISIBILITY_DATABASE_NAME,
+                        VisibilityDocument.NAMESPACE,
+                        /*id=*/ prefix + "Email",
+                        /*typePropertyPaths=*/ Collections.emptyMap()));
+        assertThat(e).hasMessageThat().contains(
+                "Document (VS#Pkg$VS#Db/, package$database1/Email) not found.");
+    }
+
+    @Test
+    public void testRemoveVisibility_noRemainingSettings() throws Exception {
+        // Create a non-all-default visibility document
+        VisibilityDocument visibilityDocument = new VisibilityDocument.Builder("Email")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .setCreationTimestampMillis(12345L)
+                .build();
+
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("Email").build());
+
+        // Set schema Email and its visibility document to AppSearch database1
+        mAppSearchImpl.setSchema(
+                "package",
+                "database1",
+                schemas,
+                /*visibilityDocuments=*/ ImmutableList.of(visibilityDocument),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+        String prefix = PrefixUtil.createPrefix("package", "database1");
+        VisibilityDocument expectedDocument = new VisibilityDocument.Builder(prefix + "Email")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .setCreationTimestampMillis(12345L)
+                .build();
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix + "Email"))
+                .isEqualTo(expectedDocument);
+        // Verify the VisibilityDocument is saved to AppSearchImpl.
+        VisibilityDocument actualDocument =  new VisibilityDocument(mAppSearchImpl.getDocument(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                VisibilityDocument.NAMESPACE,
+                /*id=*/ prefix + "Email",
+                /*typePropertyPaths=*/ Collections.emptyMap()));
+        assertThat(actualDocument).isEqualTo(expectedDocument);
+
+        // remove the schema and visibility setting from AppSearch
+        mAppSearchImpl.setSchema(
+                "package",
+                "database1",
+                /*schemas=*/ new ArrayList<>(),
+                /*visibilityDocuments=*/ ImmutableList.of(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+
+        // add the schema back with an all default visibility setting.
+        mAppSearchImpl.setSchema(
+                "package",
+                "database1",
+                schemas,
+                /*visibilityDocuments=*/ ImmutableList.of(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+        // All-default visibility document won't be saved in AppSearch.
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix + "Email"))
+                .isNull();
+        // Verify there is no visibility setting for the schema.
+        AppSearchException e = assertThrows(AppSearchException.class,
+                () -> mAppSearchImpl.getDocument(
+                        VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                        VisibilityStore.VISIBILITY_DATABASE_NAME,
+                        VisibilityDocument.NAMESPACE,
+                        /*id=*/ prefix + "Email",
+                        /*typePropertyPaths=*/ Collections.emptyMap()));
+        assertThat(e).hasMessageThat().contains(
+                "Document (VS#Pkg$VS#Db/, package$database1/Email) not found.");
+    }
+
+    @Test
+    public void testCloseAndReopen_visibilityInfoRetains() throws Exception {
+        // set Schema and visibility to AppSearch
+        VisibilityDocument visibilityDocument = new VisibilityDocument.Builder("Email")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .setCreationTimestampMillis(12345L)
+                .build();
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("Email").build());
+        mAppSearchImpl.setSchema(
+                "packageName",
+                "databaseName",
+                schemas,
+                ImmutableList.of(visibilityDocument),
+                /*forceOverride=*/ true,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // close and re-open AppSearchImpl, the visibility document retains
+        mAppSearchImpl.close();
+        mAppSearchImpl = AppSearchImpl.create(
+                mAppSearchDir,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/ null,
+                ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
+
+        String prefix = PrefixUtil.createPrefix("packageName", "databaseName");
+        VisibilityDocument expectedDocument = new VisibilityDocument.Builder(prefix + "Email")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .setCreationTimestampMillis(12345L)
+                .build();
+
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix + "Email"))
+                .isEqualTo(expectedDocument);
+        // Verify the VisibilityDocument is saved to AppSearchImpl.
+        VisibilityDocument actualDocument =  new VisibilityDocument(mAppSearchImpl.getDocument(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                VisibilityDocument.NAMESPACE,
+                /*id=*/ prefix + "Email",
+                /*typePropertyPaths=*/ Collections.emptyMap()));
+        assertThat(actualDocument).isEqualTo(expectedDocument);
+
+        // remove schema and visibility document
+        mAppSearchImpl.setSchema(
+                "packageName",
+                "databaseName",
+                ImmutableList.of(),
+                ImmutableList.of(),
+                /*forceOverride=*/ true,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // close and re-open AppSearchImpl, the visibility document removed
+        mAppSearchImpl.close();
+        mAppSearchImpl = AppSearchImpl.create(
+                mAppSearchDir,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/ null,
+                ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
+
+        assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix + "Email")).isNull();
+        // Verify the VisibilityDocument is removed from AppSearchImpl.
+        AppSearchException e = assertThrows(AppSearchException.class,
+                () -> mAppSearchImpl.getDocument(
+                        VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                        VisibilityStore.VISIBILITY_DATABASE_NAME,
+                        VisibilityDocument.NAMESPACE,
+                        /*id=*/ prefix + "Email",
+                        /*typePropertyPaths=*/ Collections.emptyMap()));
+        assertThat(e).hasMessageThat().contains(
+                "Document (VS#Pkg$VS#Db/, packageName$databaseName/Email) not found.");
+    }
+
+    @Test
+    public void testGetSchema_global() throws Exception {
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("Type").build());
+
+        // Create a new mAppSearchImpl with a mock Visibility Checker
+        mAppSearchImpl.close();
+        File tempFolder = mTemporaryFolder.newFolder();
+        VisibilityChecker mockVisibilityChecker =
+                (callerAccess, packageName, prefixedSchema, visibilityStore) -> true;
+        mAppSearchImpl = AppSearchImpl.create(
+                tempFolder,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/ null,
+                ALWAYS_OPTIMIZE,
+                mockVisibilityChecker);
+
+        mAppSearchImpl.setSchema(
+                "package",
+                "database",
+                schemas,
+                /*visibilityDocuments=*/ImmutableList.of(
+                        new VisibilityDocument.Builder("Type")
+                                .setNotDisplayedBySystem(true).build()),
+                /*forceOverride=*/false,
+                /*version=*/0,
+                /*setSchemaStatsBuilder=*/null);
+
+        // Get this schema as another package
+        GetSchemaResponse getResponse = mAppSearchImpl.getSchema(
+                "package",
+                "database",
+                new CallerAccess(/*callingPackageName=*/"com.android.appsearch.fake.package"));
+        assertThat(getResponse.getSchemas()).containsExactlyElementsIn(schemas);
+        assertThat(getResponse.getSchemaTypesNotDisplayedBySystem()).containsExactly("Type");
+    }
+
+    @Test
+    public void testGetSchema_nonExistentApp() throws Exception {
+        // Add a schema. The test loses meaning if the schema is completely empty.
+        mAppSearchImpl.setSchema(
+                "package",
+                "database",
+                Collections.singletonList(new AppSearchSchema.Builder("Type").build()),
+                /*visibilityDocuments=*/ImmutableList.of(),
+                /*forceOverride=*/false,
+                /*version=*/0,
+                /*setSchemaStatsBuilder=*/null);
+
+        // Try to get the schema of a nonexistent package.
+        GetSchemaResponse getResponse = mAppSearchImpl.getSchema(
+                "com.android.appsearch.fake.package",
+                "database",
+                new CallerAccess(/*callingPackageName=*/"package"));
+        assertThat(getResponse.getSchemas()).isEmpty();
+        assertThat(getResponse.getSchemaTypesNotDisplayedBySystem()).isEmpty();
+    }
+
+    @Test
+    public void testGetSchema_noAccess() throws Exception {
+        List<AppSearchSchema> schemas =
+                Collections.singletonList(new AppSearchSchema.Builder("Type").build());
+        mAppSearchImpl.setSchema(
+                "package",
+                "database",
+                schemas,
+                /*visibilityDocuments=*/ImmutableList.of(),
+                /*forceOverride=*/false,
+                /*version=*/1,
+                /*setSchemaStatsBuilder=*/null);
+        GetSchemaResponse getResponse = mAppSearchImpl.getSchema(
+                "package",
+                "database",
+                new CallerAccess(/*callingPackageName=*/
+                        "com.android.appsearch.fake.package"));
+        assertThat(getResponse.getSchemas()).isEmpty();
+        assertThat(getResponse.getSchemaTypesNotDisplayedBySystem()).isEmpty();
+        assertThat(getResponse.getVersion()).isEqualTo(0);
+
+        // Make sure the test is hooked up right by calling getSchema with the same parameters but
+        // from the same package
+        getResponse = mAppSearchImpl.getSchema(
+                "package",
+                "database",
+                new CallerAccess(/*callingPackageName=*/"package"));
+        assertThat(getResponse.getSchemas()).containsExactlyElementsIn(schemas);
+    }
+
+    @Test
+    public void testGetSchema_global_partialAccess() throws Exception {
+        List<AppSearchSchema> schemas = ImmutableList.of(
+                new AppSearchSchema.Builder("VisibleType").build(),
+                new AppSearchSchema.Builder("PrivateType").build());
+
+        // Create a new mAppSearchImpl with a mock Visibility Checker
+        mAppSearchImpl.close();
+        File tempFolder = mTemporaryFolder.newFolder();
+        VisibilityChecker mockVisibilityChecker =
+                (callerAccess, packageName, prefixedSchema, visibilityStore)
+                        -> prefixedSchema.endsWith("VisibleType");
+        mAppSearchImpl = AppSearchImpl.create(
+                tempFolder,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/ null,
+                ALWAYS_OPTIMIZE,
+                mockVisibilityChecker);
+
+        mAppSearchImpl.setSchema(
+                "package",
+                "database",
+                schemas,
+                /*visibilityDocuments=*/ImmutableList.of(
+                        new VisibilityDocument.Builder("VisibleType")
+                                .setNotDisplayedBySystem(true)
+                                .build(),
+                        new VisibilityDocument.Builder("PrivateType")
+                                .setNotDisplayedBySystem(true)
+                                .build()),
+                /*forceOverride=*/false,
+                /*version=*/1,
+                /*setSchemaStatsBuilder=*/null);
+
+        GetSchemaResponse getResponse = mAppSearchImpl.getSchema(
+                "package",
+                "database",
+                new CallerAccess(/*callingPackageName=*/
+                        "com.android.appsearch.fake.package"));
+        assertThat(getResponse.getSchemas()).containsExactly(schemas.get(0));
+        assertThat(getResponse.getSchemaTypesNotDisplayedBySystem()).containsExactly("VisibleType");
+        assertThat(getResponse.getVersion()).isEqualTo(1);
+    }
+
+    @Test
+    public void testDispatchObserver_samePackage_noVisStore_accept() throws Exception {
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(new AppSearchSchema.Builder("Type1").build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                /*listeningPackageAccess=*/mSelfCallerAccess,
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Insert a valid doc
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.putDocument(
+                mContext.getPackageName(),
+                "database1",
+                new GenericDocument.Builder<>("namespace1", "id1", "Type1").build(),
+                /*sendChangeNotifications=*/ true,
+                /*logger=*/null);
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+
+        // Dispatch notifications
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).containsExactly(
+                new DocumentChangeInfo(
+                        mContext.getPackageName(),
+                        "database1",
+                        "namespace1",
+                        "Type1",
+                        ImmutableSet.of("id1")));
+    }
+
+    @Test
+    public void testDispatchObserver_samePackage_withVisStore_accept() throws Exception {
+        // Make a visibility checker that rejects everything
+        final VisibilityChecker rejectChecker =
+                (callerAccess, packageName, prefixedSchema, visibilityStore) -> false;
+        mAppSearchImpl.close();
+        mAppSearchImpl = AppSearchImpl.create(
+                mAppSearchDir,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/null,
+                ALWAYS_OPTIMIZE,
+                rejectChecker);
+
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(new AppSearchSchema.Builder("Type1").build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                /*listeningPackageAccess=*/mSelfCallerAccess,
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Insert a valid doc
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.putDocument(
+                mContext.getPackageName(),
+                "database1",
+                new GenericDocument.Builder<>("namespace1", "id1", "Type1").build(),
+                /*sendChangeNotifications=*/ true,
+                /*logger=*/null);
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+
+        // Dispatch notifications
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).containsExactly(
+                new DocumentChangeInfo(
+                        mContext.getPackageName(),
+                        "database1",
+                        "namespace1",
+                        "Type1",
+                        ImmutableSet.of("id1")));
+    }
+
+    @Test
+    public void testDispatchObserver_differentPackage_noVisStore_reject() throws Exception {
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(new AppSearchSchema.Builder("Type1").build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Register an observer from a simulated different package
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                new CallerAccess(/*callingPackageName=*/
+                    "com.fake.Listening.package"),
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Insert a valid doc
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.putDocument(
+                mContext.getPackageName(),
+                "database1",
+                new GenericDocument.Builder<>("namespace1", "id1", "Type1").build(),
+                /*sendChangeNotifications=*/ true,
+                /*logger=*/null);
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+
+        // Dispatch notifications
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testDispatchObserver_differentPackage_withVisStore_accept() throws Exception {
+        final String fakeListeningPackage = "com.fake.listening.package";
+
+        // Make a visibility checker that allows only fakeListeningPackage.
+        final VisibilityChecker visibilityChecker =
+                (callerAccess, packageName, prefixedSchema, visibilityStore)
+                        -> callerAccess.getCallingPackageName().equals(fakeListeningPackage);
+        mAppSearchImpl.close();
+        mAppSearchImpl = AppSearchImpl.create(
+                mAppSearchDir,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/null,
+                ALWAYS_OPTIMIZE,
+                visibilityChecker);
+
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(new AppSearchSchema.Builder("Type1").build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                new CallerAccess(/*callingPackageName=*/fakeListeningPackage),
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Insert a valid doc
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.putDocument(
+                mContext.getPackageName(),
+                "database1",
+                new GenericDocument.Builder<>("namespace1", "id1", "Type1").build(),
+                /*sendChangeNotifications=*/ true,
+                /*logger=*/null);
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+
+        // Dispatch notifications
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).containsExactly(
+                new DocumentChangeInfo(
+                        mContext.getPackageName(),
+                        "database1",
+                        "namespace1",
+                        "Type1",
+                        ImmutableSet.of("id1")));
+    }
+
+    @Test
+    public void testDispatchObserver_differentPackage_withVisStore_reject() throws Exception {
+        final String fakeListeningPackage = "com.fake.Listening.package";
+
+        // Make a visibility checker that rejects everything.
+        final VisibilityChecker rejectChecker =
+                (callerAccess, packageName, prefixedSchema, visibilityStore) -> false;
+        mAppSearchImpl.close();
+        mAppSearchImpl = AppSearchImpl.create(
+                mAppSearchDir,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/null,
+                ALWAYS_OPTIMIZE,
+                rejectChecker);
+
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(new AppSearchSchema.Builder("Type1").build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                new CallerAccess(/*callingPackageName=*/fakeListeningPackage),
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Insert a doc
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.putDocument(
+                mContext.getPackageName(),
+                "database1",
+                new GenericDocument.Builder<>("namespace1", "id1", "Type1").build(),
+                /*sendChangeNotifications=*/ true,
+                /*logger=*/null);
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+
+        // Dispatch notifications
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testAddObserver_schemaChange_added() throws Exception {
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                /*listeningPackageAccess=*/mSelfCallerAccess,
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Add a schema type
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(new AppSearchSchema.Builder("Type1").build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+
+        // Dispatch notifications
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(),
+                        "database1",
+                        ImmutableSet.of("Type1")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+
+        // Add two more schema types without touching the existing one
+        observer.clear();
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1").build(),
+                        new AppSearchSchema.Builder("Type2").build(),
+                        new AppSearchSchema.Builder("Type3").build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+
+        // Dispatch notifications
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), "database1", ImmutableSet.of("Type2", "Type3")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testAddObserver_schemaChange_removed() throws Exception {
+        // Add a schema type
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1").build(),
+                        new AppSearchSchema.Builder("Type2").build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                /*listeningPackageAccess=*/mSelfCallerAccess,
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Remove Type2
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(new AppSearchSchema.Builder("Type1").build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ true,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Dispatch notifications
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(),
+                        "database1",
+                        ImmutableSet.of("Type2")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testAddObserver_schemaChange_contents() throws Exception {
+        // Add a schema
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1").build(),
+                        new AppSearchSchema.Builder("Type2")
+                                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                        "booleanProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
+                                        .build())
+                                .build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                /*listeningPackageAccess=*/mSelfCallerAccess,
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Update the schema, but don't make any actual changes
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1").build(),
+                        new AppSearchSchema.Builder("Type2")
+                                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                        "booleanProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
+                                        .build())
+                                .build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 1,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Dispatch notifications
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+
+        // Now update the schema again, but this time actually make a change (cardinality of the
+        // property)
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1").build(),
+                        new AppSearchSchema.Builder("Type2")
+                                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                        "booleanProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .build())
+                                .build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 2,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Dispatch notifications
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), "database1", ImmutableSet.of("Type2")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testAddObserver_schemaChange_contents_skipBySpec() throws Exception {
+        // Add a schema
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1")
+                                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                        "booleanProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
+                                        .build())
+                                .build(),
+                        new AppSearchSchema.Builder("Type2")
+                                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                        "booleanProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
+                                        .build())
+                                .build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Register an observer that only listens for Type2
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                /*listeningPackageAccess=*/mSelfCallerAccess,
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().addFilterSchemas("Type2").build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Update both types of the schema (changed cardinalities)
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1")
+                                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                        "booleanProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .build())
+                                .build(),
+                        new AppSearchSchema.Builder("Type2")
+                                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                        "booleanProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .build())
+                                .build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Dispatch notifications
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), "database1", ImmutableSet.of("Type2")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testAddObserver_schemaChange_visibilityOnly() throws Exception {
+        final String fakeListeningPackage = "com.fake.listening.package";
+
+        // Make a fake visibility checker that actually looks at visibility store
+        final VisibilityChecker visibilityChecker =
+                (callerAccess, packageName, prefixedSchema, visibilityStore)
+                        -> {
+                    if (!callerAccess.getCallingPackageName().equals(fakeListeningPackage)) {
+                        return false;
+                    }
+                    Set<String> allowedPackages = new ArraySet<>(
+                            visibilityStore.getVisibility(prefixedSchema).getPackageNames());
+                    return allowedPackages.contains(fakeListeningPackage);
+                };
+        mAppSearchImpl.close();
+        mAppSearchImpl = AppSearchImpl.create(
+                mAppSearchDir,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/null,
+                ALWAYS_OPTIMIZE,
+                visibilityChecker);
+
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                new CallerAccess(/*callingPackageName=*/fakeListeningPackage),
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Add a schema where both types are visible to the fake package.
+        List<AppSearchSchema> schemas = ImmutableList.of(
+                new AppSearchSchema.Builder("Type1").build(),
+                new AppSearchSchema.Builder("Type2").build());
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                schemas,
+                /*visibilityDocuments=*/ ImmutableList.of(
+                        new VisibilityDocument.Builder("Type1")
+                                .addVisibleToPackage(
+                                        new PackageIdentifier(fakeListeningPackage, new byte[0]))
+                                .build(),
+                        new VisibilityDocument.Builder("Type2")
+                                .addVisibleToPackage(
+                                        new PackageIdentifier(fakeListeningPackage, new byte[0]))
+                                .build()
+                ),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Notifications of addition should now be dispatched
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), "database1", ImmutableSet.of("Type1", "Type2")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        observer.clear();
+
+        // Update schema, keeping the types identical but denying visibility to type2
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                schemas,
+                /*visibilityDocuments=*/ ImmutableList.of(
+                        new VisibilityDocument.Builder("Type1")
+                                .addVisibleToPackage(
+                                        new PackageIdentifier(fakeListeningPackage, new byte[0]))
+                                .build(),
+                        new VisibilityDocument.Builder("Type2").build()
+                ),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Dispatch notifications. This should look like a deletion of Type2.
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), "database1", ImmutableSet.of("Type2")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        observer.clear();
+
+        // Now update Type2 and make sure no further notification is received.
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1").build(),
+                        new AppSearchSchema.Builder("Type2")
+                                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                        "booleanProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .build())
+                                .build()),
+                /*visibilityDocuments=*/ ImmutableList.of(
+                        new VisibilityDocument.Builder("Type1")
+                                .addVisibleToPackage(
+                                        new PackageIdentifier(fakeListeningPackage, new byte[0]))
+                                .build(),
+                        new VisibilityDocument.Builder("Type2").build()
+                ),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+
+        // Grant visibility to Type2 again and make sure it appears
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1").build(),
+                        new AppSearchSchema.Builder("Type2")
+                                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                        "booleanProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .build())
+                                .build()),
+                /*visibilityDocuments=*/ImmutableList.of(
+                        new VisibilityDocument.Builder("Type1")
+                                .addVisibleToPackage(
+                                        new PackageIdentifier(fakeListeningPackage, new byte[0]))
+                                .build(),
+                        new VisibilityDocument.Builder("Type2")
+                                .addVisibleToPackage(
+                                        new PackageIdentifier(fakeListeningPackage, new byte[0]))
+                                .build()
+                ),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Dispatch notifications. This should look like a creation of Type2.
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), "database1", ImmutableSet.of("Type2")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testAddObserver_schemaChange_visibilityAndContents() throws Exception {
+        final String fakeListeningPackage = "com.fake.listening.package";
+
+        // Make a visibility checker that allows fakeListeningPackage access only to Type2.
+        final VisibilityChecker visibilityChecker =
+                (callerAccess, packageName, prefixedSchema, visibilityStore)
+                        -> callerAccess.getCallingPackageName().equals(fakeListeningPackage)
+                        && prefixedSchema.endsWith("Type2");
+        mAppSearchImpl.close();
+        mAppSearchImpl = AppSearchImpl.create(
+                mAppSearchDir,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/null,
+                ALWAYS_OPTIMIZE,
+                visibilityChecker);
+
+        // Add a schema.
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1")
+                                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                        "booleanProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
+                                        .build())
+                                .build(),
+                        new AppSearchSchema.Builder("Type2")
+                                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                        "booleanProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
+                                        .build())
+                                .build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                new CallerAccess(/*callingPackageName=*/fakeListeningPackage),
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Update both types of the schema (changed cardinalities)
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1")
+                                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                        "booleanProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .build())
+                                .build(),
+                        new AppSearchSchema.Builder("Type2")
+                                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                        "booleanProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                                        .build())
+                                .build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Dispatch notifications
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), "database1", ImmutableSet.of("Type2")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testAddObserver_schemaChange_partialVisibility_removed() throws Exception {
+        final String fakeListeningPackage = "com.fake.listening.package";
+
+        // Make a visibility checker that allows fakeListeningPackage access only to Type2.
+        final VisibilityChecker visibilityChecker =
+                (callerAccess, packageName, prefixedSchema, visibilityStore)
+                        -> callerAccess.getCallingPackageName().equals(fakeListeningPackage)
+                        && prefixedSchema.endsWith("Type2");
+        mAppSearchImpl.close();
+        mAppSearchImpl = AppSearchImpl.create(
+                mAppSearchDir,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/null,
+                ALWAYS_OPTIMIZE,
+                visibilityChecker);
+
+        // Add a schema.
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1").build(),
+                        new AppSearchSchema.Builder("Type2").build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                new CallerAccess(/*callingPackageName=*/fakeListeningPackage),
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Remove Type1
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(new AppSearchSchema.Builder("Type2").build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ true,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Dispatch notifications. Nothing should appear since Type1 is not visible to us.
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+
+        // Now remove Type2. This should cause a notification.
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ true,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), "database1", ImmutableSet.of("Type2")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testAddObserver_schemaChange_multipleObservers() throws Exception {
+        // Create two fake packages. One can access Type1, one can access Type2, they both can
+        // access Type3, and no one can access Type4.
+        final String fakePackage1 = "com.fake.listening.package1";
+
+        final String fakePackage2 = "com.fake.listening.package2";
+
+        final VisibilityChecker visibilityChecker =
+                (callerAccess, packageName, prefixedSchema, visibilityStore)
+                        -> {
+                    if (prefixedSchema.endsWith("Type1")) {
+                        return callerAccess.getCallingPackageName().equals(fakePackage1);
+                    } else if (prefixedSchema.endsWith("Type2")) {
+                        return callerAccess.getCallingPackageName().equals(fakePackage2);
+                    } else if (prefixedSchema.endsWith("Type3")) {
+                        return false;
+                    } else if (prefixedSchema.endsWith("Type4")) {
+                        return true;
+                    } else {
+                        throw new IllegalArgumentException(prefixedSchema);
+                    }
+                };
+        mAppSearchImpl.close();
+        mAppSearchImpl = AppSearchImpl.create(
+                mAppSearchDir,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/null,
+                ALWAYS_OPTIMIZE,
+                visibilityChecker);
+
+        // Add a schema.
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1").build(),
+                        new AppSearchSchema.Builder("Type2").build(),
+                        new AppSearchSchema.Builder("Type3").build(),
+                        new AppSearchSchema.Builder("Type4").build()
+                ),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Register three observers: one in each package, and another in package1 with a filter.
+        TestObserverCallback observerPkg1NoFilter = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                new CallerAccess(/*callingPackageName=*/fakePackage1),
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observerPkg1NoFilter);
+
+        TestObserverCallback observerPkg2NoFilter = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                new CallerAccess(/*callingPackageName=*/fakePackage2),
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observerPkg2NoFilter);
+
+        TestObserverCallback observerPkg1FilterType4 = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                new CallerAccess(/*callingPackageName=*/fakePackage1),
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().addFilterSchemas("Type4").build(),
+                MoreExecutors.directExecutor(),
+                observerPkg1FilterType4);
+
+        // Remove everything
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ true,
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Dispatch notifications.
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+
+        // observerPkg1NoFilter should see Type1 and Type4 vanish.
+        // observerPkg2NoFilter should see Type2 and Type4 vanish.
+        // observerPkg2WithFilter should see Type4 vanish.
+        assertThat(observerPkg1NoFilter.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), "database1", ImmutableSet.of("Type1", "Type4"))
+        );
+        assertThat(observerPkg1NoFilter.getDocumentChanges()).isEmpty();
+
+        assertThat(observerPkg2NoFilter.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), "database1", ImmutableSet.of("Type2", "Type4"))
+        );
+        assertThat(observerPkg2NoFilter.getDocumentChanges()).isEmpty();
+
+        assertThat(observerPkg1FilterType4.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), "database1", ImmutableSet.of("Type4"))
+        );
+        assertThat(observerPkg1FilterType4.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testAddObserver_schemaChange_noChangeIfIncompatible() throws Exception {
+        // Add a schema with two types.
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Type1")
+                                .addProperty(
+                                        new AppSearchSchema.StringPropertyConfig.Builder("strProp")
+                                                .setCardinality(
+                                                        AppSearchSchema.PropertyConfig
+                                                                .CARDINALITY_OPTIONAL)
+                                                .build()
+                                ).build(),
+                        new AppSearchSchema.Builder("Type2")
+                                .addProperty(
+                                        new AppSearchSchema.StringPropertyConfig.Builder("strProp")
+                                                .setCardinality(
+                                                        AppSearchSchema.PropertyConfig
+                                                                .CARDINALITY_OPTIONAL)
+                                                .build()
+                                ).build()
+                ),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 1,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mAppSearchImpl.registerObserverCallback(
+                new CallerAccess(/*callingPackageName=*/mContext.getPackageName()),
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                MoreExecutors.directExecutor(),
+                observer);
+
+        // Update schema to try to make an incompatible change to Type1, and a compatible change to
+        // Type2.
+        List<AppSearchSchema> updatedSchemaTypes = ImmutableList.of(
+                new AppSearchSchema.Builder("Type1")
+                        .addProperty(
+                                new AppSearchSchema.StringPropertyConfig.Builder("strProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
+                                        .build()
+                        ).build(),
+                new AppSearchSchema.Builder("Type2")
+                        .addProperty(
+                                new AppSearchSchema.StringPropertyConfig.Builder("strProp")
+                                        .setCardinality(
+                                                AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                                        .build()
+                        ).build()
+        );
+        SetSchemaResponse setSchemaResponse = mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                updatedSchemaTypes,
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 2,
+                /*setSchemaStatsBuilder=*/ null);
+        assertThat(setSchemaResponse.getDeletedTypes()).isEmpty();
+        assertThat(setSchemaResponse.getIncompatibleTypes()).containsExactly("Type1");
+
+        // Dispatch notifications. Nothing should appear since the schema was incompatible and has
+        // not changed.
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+
+        // Now force apply the schemas Type2. This should cause a notification.
+        mAppSearchImpl.setSchema(
+                mContext.getPackageName(),
+                "database1",
+                updatedSchemaTypes,
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ true,
+                /*version=*/ 3,
+                /*setSchemaStatsBuilder=*/ null);
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mAppSearchImpl.dispatchAndClearChangeNotifications();
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), "database1", ImmutableSet.of("Type1", "Type2")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
 }
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchLoggerTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchLoggerTest.java
index 75966bf..30909d6 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchLoggerTest.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchLoggerTest.java
@@ -74,7 +74,8 @@
                 mTemporaryFolder.newFolder(),
                 new UnlimitedLimitConfig(),
                 /*initStatsBuilder=*/ null,
-                ALWAYS_OPTIMIZE);
+                ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
         mLogger = new SimpleTestLogger();
     }
 
@@ -335,16 +336,18 @@
                 mTemporaryFolder.newFolder(),
                 new UnlimitedLimitConfig(),
                 initStatsBuilder,
-                ALWAYS_OPTIMIZE);
+                ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
         InitializeStats iStats = initStatsBuilder.build();
         appSearchImpl.close();
 
         assertThat(iStats).isNotNull();
+        // If the process goes really fast, the total latency could be 0. Since the default of total
+        // latency is also 0, we just remove the assert about NativeLatencyMillis.
         assertThat(iStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
         // Total latency captured in LocalStorage
         assertThat(iStats.getTotalLatencyMillis()).isEqualTo(0);
         assertThat(iStats.hasDeSync()).isFalse();
-        assertThat(iStats.getNativeLatencyMillis()).isGreaterThan(0);
         assertThat(iStats.getDocumentStoreDataStatus()).isEqualTo(
                 InitializeStatsProto.DocumentStoreDataStatus.NO_DATA_LOSS_VALUE);
         assertThat(iStats.getDocumentCount()).isEqualTo(0);
@@ -363,7 +366,8 @@
                 folder,
                 new UnlimitedLimitConfig(),
                 /*initStatsBuilder=*/ null,
-                ALWAYS_OPTIMIZE);
+                ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
         List<AppSearchSchema> schemas = ImmutableList.of(
                 new AppSearchSchema.Builder("Type1").build(),
                 new AppSearchSchema.Builder("Type2").build());
@@ -371,9 +375,7 @@
                 testPackageName,
                 testDatabase,
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -381,26 +383,38 @@
                 new GenericDocument.Builder<>("namespace", "id1", "Type1").build();
         GenericDocument doc2 =
                 new GenericDocument.Builder<>("namespace", "id2", "Type1").build();
-        appSearchImpl.putDocument(testPackageName, testDatabase, doc1, mLogger);
-        appSearchImpl.putDocument(testPackageName, testDatabase, doc2, mLogger);
+        appSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                doc1,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
+        appSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                doc2,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
         appSearchImpl.close();
 
         // Create another appsearchImpl on the same folder
         InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
         appSearchImpl = AppSearchImpl.create(
-                folder, new UnlimitedLimitConfig(), initStatsBuilder, ALWAYS_OPTIMIZE);
+                folder, new UnlimitedLimitConfig(), initStatsBuilder, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
         InitializeStats iStats = initStatsBuilder.build();
 
         assertThat(iStats).isNotNull();
+        // If the process goes really fast, the total latency could be 0. Since the default of total
+        // latency is also 0, we just remove the assert about NativeLatencyMillis.
         assertThat(iStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
         // Total latency captured in LocalStorage
         assertThat(iStats.getTotalLatencyMillis()).isEqualTo(0);
         assertThat(iStats.hasDeSync()).isFalse();
-        assertThat(iStats.getNativeLatencyMillis()).isGreaterThan(0);
         assertThat(iStats.getDocumentStoreDataStatus()).isEqualTo(
                 InitializeStatsProto.DocumentStoreDataStatus.NO_DATA_LOSS_VALUE);
         assertThat(iStats.getDocumentCount()).isEqualTo(2);
-        assertThat(iStats.getSchemaTypeCount()).isEqualTo(2);
+        assertThat(iStats.getSchemaTypeCount()).isEqualTo(4); // +2 for VisibilitySchema
         assertThat(iStats.hasReset()).isEqualTo(false);
         assertThat(iStats.getResetStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
         appSearchImpl.close();
@@ -413,7 +427,8 @@
         final File folder = mTemporaryFolder.newFolder();
 
         AppSearchImpl appSearchImpl = AppSearchImpl.create(
-                folder, new UnlimitedLimitConfig(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+                folder, new UnlimitedLimitConfig(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
 
         List<AppSearchSchema> schemas = ImmutableList.of(
                 new AppSearchSchema.Builder("Type1").build(),
@@ -422,9 +437,7 @@
                 testPackageName,
                 testDatabase,
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -432,7 +445,12 @@
         // Insert a valid doc
         GenericDocument doc1 =
                 new GenericDocument.Builder<>("namespace", "id1", "Type1").build();
-        appSearchImpl.putDocument(testPackageName, testDatabase, doc1, mLogger);
+        appSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                doc1,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
 
         // Insert the invalid doc with an invalid namespace right into icing
         DocumentProto invalidDoc = DocumentProto.newBuilder()
@@ -447,7 +465,8 @@
         // Create another appsearchImpl on the same folder
         InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
         appSearchImpl = AppSearchImpl.create(
-                folder, new UnlimitedLimitConfig(), initStatsBuilder, ALWAYS_OPTIMIZE);
+                folder, new UnlimitedLimitConfig(), initStatsBuilder, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
         InitializeStats iStats = initStatsBuilder.build();
 
         // Some of other fields are already covered by AppSearchImplTest#testReset()
@@ -475,9 +494,7 @@
                 testPackageName,
                 testDatabase,
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -487,7 +504,12 @@
                         .setPropertyString("subject", "testPut example1")
                         .build();
 
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document, mLogger);
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                document,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
 
         PutDocumentStats pStats = mLogger.mPutDocumentStats;
         assertThat(pStats).isNotNull();
@@ -517,9 +539,7 @@
                 testPackageName,
                 testDatabase,
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -530,7 +550,12 @@
                         .build();
 
         AppSearchException exception = Assert.assertThrows(AppSearchException.class,
-                () -> mAppSearchImpl.putDocument(testPackageName, testDatabase, document, mLogger));
+                () -> mAppSearchImpl.putDocument(
+                        testPackageName,
+                        testDatabase,
+                        document,
+                        /*sendChangeNotifications=*/ false,
+                        mLogger));
         assertThat(exception.getResultCode()).isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
 
         PutDocumentStats pStats = mLogger.mPutDocumentStats;
@@ -558,9 +583,7 @@
                 testPackageName,
                 testDatabase,
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -576,9 +599,24 @@
                 new GenericDocument.Builder<>("namespace", "id3", "type")
                         .setPropertyString("subject", "testPut 3")
                         .build();
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document1, mLogger);
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document2, mLogger);
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document3, mLogger);
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                document1,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                document2,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                document3,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
 
 
         // No query filters specified. package2 should only get its own documents back.
@@ -598,10 +636,11 @@
         SearchStats sStats = mLogger.mSearchStats;
 
         assertThat(sStats).isNotNull();
+        // If the process goes really fast, the total latency could be 0. Since the default of total
+        // latency is also 0, we just remove the assert about TotalLatencyMillis.
         assertThat(sStats.getPackageName()).isEqualTo(testPackageName);
         assertThat(sStats.getDatabase()).isEqualTo(testDatabase);
         assertThat(sStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
-        assertThat(sStats.getTotalLatencyMillis()).isGreaterThan(0);
         assertThat(sStats.getVisibilityScope()).isEqualTo(SearchStats.VISIBILITY_SCOPE_LOCAL);
         assertThat(sStats.getTermCount()).isEqualTo(2);
         assertThat(sStats.getQueryLength()).isEqualTo(queryStr.length());
@@ -626,9 +665,7 @@
                 testPackageName,
                 testDatabase,
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -664,15 +701,18 @@
                 testPackageName,
                 testDatabase,
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
         GenericDocument document =
                 new GenericDocument.Builder<>(testNamespace, testId, "type").build();
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         RemoveStats.Builder rStatsBuilder = new RemoveStats.Builder(testPackageName, testDatabase);
         mAppSearchImpl.remove(testPackageName, testDatabase, testNamespace, testId, rStatsBuilder);
@@ -699,16 +739,19 @@
                 testPackageName,
                 testDatabase,
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
 
         GenericDocument document =
                 new GenericDocument.Builder<>(testNamespace, testId, "type").build();
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                document,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         RemoveStats.Builder rStatsBuilder = new RemoveStats.Builder(testPackageName, testDatabase);
 
@@ -739,9 +782,7 @@
                 testPackageName,
                 testDatabase,
                 schemas,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -749,8 +790,18 @@
                 new GenericDocument.Builder<>(testNamespace, "id1", "type").build();
         GenericDocument document2 =
                 new GenericDocument.Builder<>(testNamespace, "id2", "type").build();
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document1, mLogger);
-        mAppSearchImpl.putDocument(testPackageName, testDatabase, document2, mLogger);
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                document1,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                document2,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
         // No query filters specified. package2 should only get its own documents back.
         SearchSpec searchSpec =
                 new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
@@ -784,9 +835,7 @@
                 PACKAGE_NAME,
                 DATABASE,
                 Collections.singletonList(schema1),
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -798,9 +847,7 @@
                 PACKAGE_NAME,
                 DATABASE,
                 Collections.singletonList(schema2),
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ sStatsBuilder);
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/SearchResultsImplTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/SearchResultsImplTest.java
index 9df244e..765ca3b 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/SearchResultsImplTest.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/SearchResultsImplTest.java
@@ -51,7 +51,8 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mTemporaryFolder.newFolder(),
                 new UnlimitedLimitConfig(),
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
     }
 
     @After
@@ -68,9 +69,7 @@
                 "package1",
                 "database1",
                 schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -78,7 +77,12 @@
         // Insert one package1 documents
         GenericDocument document1 = new GenericDocument.Builder<>("namespace", "id1",
                 "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Query for only 1 result per page
         SearchSpec searchSpec = new SearchSpec.Builder()
@@ -95,12 +99,12 @@
                 searchSpec,
                 /*logger=*/ null);
 
-        List<SearchResult> results = searchResults.getNextPage().get();
+        List<SearchResult> results = searchResults.getNextPageAsync().get();
         assertThat(results).hasSize(1);
         assertThat(results.get(0).getGenericDocument()).isEqualTo(document1);
 
         // We get all documents, and it shouldn't fail if we keep calling getNextPage().
-        results = searchResults.getNextPage().get();
+        results = searchResults.getNextPageAsync().get();
         assertThat(results).isEmpty();
     }
 
@@ -113,9 +117,7 @@
                 "package1",
                 "database1",
                 schema1,
-                /*visibilityStore=*/ null,
-                /*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
-                /*schemasVisibleToPackages=*/ Collections.emptyMap(),
+                /*visibilityDocuments=*/ Collections.emptyList(),
                 /*forceOverride=*/ false,
                 /*version=*/ 0,
                 /* setSchemaStatsBuilder= */ null);
@@ -127,9 +129,24 @@
                 "schema1").build();
         GenericDocument document3 = new GenericDocument.Builder<>("namespace", "id3",
                 "schema1").build();
-        mAppSearchImpl.putDocument("package1", "database1", document1, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document2, /*logger=*/ null);
-        mAppSearchImpl.putDocument("package1", "database1", document3, /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document2,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
+        mAppSearchImpl.putDocument(
+                "package1",
+                "database1",
+                document3,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/ null);
 
         // Query for only 2 result per page
         SearchSpec searchSpec = new SearchSpec.Builder()
@@ -146,18 +163,18 @@
                 searchSpec,
                 /*logger=*/ null);
         List<GenericDocument> outDocs = new ArrayList<>();
-        List<SearchResult> results = searchResults.getNextPage().get();
+        List<SearchResult> results = searchResults.getNextPageAsync().get();
         assertThat(results).hasSize(2);
         outDocs.add(results.get(0).getGenericDocument());
         outDocs.add(results.get(1).getGenericDocument());
 
-        results = searchResults.getNextPage().get();
+        results = searchResults.getNextPageAsync().get();
         assertThat(results).hasSize(1);
         outDocs.add(results.get(0).getGenericDocument());
         assertThat(outDocs).containsExactly(document1, document2, document3);
 
         // We get all documents, and it shouldn't fail if we keep calling getNextPage().
-        results = searchResults.getNextPage().get();
+        results = searchResults.getNextPageAsync().get();
         assertThat(results).isEmpty();
     }
 }
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverterTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverterTest.java
index 29aeb96..85f46c6 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverterTest.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverterTest.java
@@ -23,12 +23,14 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import androidx.annotation.NonNull;
-import androidx.appsearch.app.PackageIdentifier;
 import androidx.appsearch.app.SearchSpec;
-import androidx.appsearch.exceptions.AppSearchException;
+import androidx.appsearch.localstorage.AppSearchImpl;
+import androidx.appsearch.localstorage.OptimizeStrategy;
+import androidx.appsearch.localstorage.UnlimitedLimitConfig;
 import androidx.appsearch.localstorage.util.PrefixUtil;
+import androidx.appsearch.localstorage.visibilitystore.CallerAccess;
 import androidx.appsearch.localstorage.visibilitystore.VisibilityStore;
+import androidx.appsearch.testutil.AppSearchTestUtils;
 
 import com.google.android.icing.proto.ResultSpecProto;
 import com.google.android.icing.proto.SchemaTypeConfigProto;
@@ -37,13 +39,19 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 public class SearchSpecToProtoConverterTest {
+    /** An optimize strategy that always triggers optimize. */
+    public static final OptimizeStrategy ALWAYS_OPTIMIZE = optimizeInfo -> true;
+
+    @Rule
+    public final TemporaryFolder mTemporaryFolder = new TemporaryFolder();
 
     @Test
     public void testToSearchSpecProto() throws Exception {
@@ -117,7 +125,7 @@
         assertThat(resultSpecProto.getNumPerPage()).isEqualTo(123);
         assertThat(resultSpecProto.getSnippetSpec().getNumToSnippet()).isEqualTo(234);
         assertThat(resultSpecProto.getSnippetSpec().getNumMatchesPerProperty()).isEqualTo(345);
-        assertThat(resultSpecProto.getSnippetSpec().getMaxWindowBytes()).isEqualTo(456);
+        assertThat(resultSpecProto.getSnippetSpec().getMaxWindowUtf32Length()).isEqualTo(456);
     }
 
     @Test
@@ -423,14 +431,20 @@
     }
 
     @Test
-    public void testRemoveInaccessibleSchemaFilter() {
-        String prefix = PrefixUtil.createPrefix("package", "database");
+    public void testRemoveInaccessibleSchemaFilter() throws Exception {
+        AppSearchImpl appSearchImpl = AppSearchImpl.create(
+                mTemporaryFolder.newFolder(),
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/null,
+                ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
+        VisibilityStore visibilityStore = new VisibilityStore(appSearchImpl);
 
-        SearchSpec searchSpec = new SearchSpec.Builder().build();
-
+        final String prefix = PrefixUtil.createPrefix("package", "database");
         SchemaTypeConfigProto schemaTypeConfigProto =
                 SchemaTypeConfigProto.newBuilder().getDefaultInstanceForType();
-        SearchSpecToProtoConverter converter = new SearchSpecToProtoConverter(searchSpec,
+        SearchSpecToProtoConverter converter = new SearchSpecToProtoConverter(
+                new SearchSpec.Builder().build(),
                 /*prefixes=*/ImmutableSet.of(prefix),
                 /*namespaceMap=*/ImmutableMap.of(
                         prefix, ImmutableSet.of("package$database/namespace1")),
@@ -441,27 +455,11 @@
                                 "package$database/schema3", schemaTypeConfigProto)));
 
         converter.removeInaccessibleSchemaFilter(
-                /*callerPackageName=*/"otherPackageName",
-                new VisibilityStore() {
-                    @Override
-                    public void setVisibility(@NonNull String packageName,
-                            @NonNull String databaseName,
-                            @NonNull Set<String> schemasNotDisplayedBySystem,
-                            @NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages)
-                            throws AppSearchException {
-
-                    }
-
-                    @Override
-                    public boolean isSchemaSearchableByCaller(@NonNull String packageName,
-                            @NonNull String databaseName, @NonNull String prefixedSchema,
-                            int callerUid, boolean callerHasSystemAccess) {
-                        // filter out schema 2 which is not searchable for user.
-                        return !prefixedSchema.equals(prefix + "schema2");
-                    }
-                },
-                /*callerUid=*/-1,
-                /*callerHasSystemAccess=*/true);
+                new CallerAccess(/*callingPackageName=*/"otherPackageName"),
+                visibilityStore,
+                AppSearchTestUtils.createMockVisibilityChecker(
+                        /*visiblePrefixedSchemas=*/ ImmutableSet.of(
+                                prefix + "schema1", prefix + "schema3")));
 
         SearchSpecProto searchSpecProto =
                 converter.toSearchSpecProto(/*queryExpression=*/"");
@@ -506,27 +504,9 @@
 
         // remove all target schema filter, and the query becomes nothing to search.
         nonEmptyConverter.removeInaccessibleSchemaFilter(
-                /*callerPackageName=*/"otherPackageName",
-                new VisibilityStore() {
-                    @Override
-                    public void setVisibility(@NonNull String packageName,
-                            @NonNull String databaseName,
-                            @NonNull Set<String> schemasNotDisplayedBySystem,
-                            @NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages)
-                            throws AppSearchException {
-
-                    }
-
-                    @Override
-                    public boolean isSchemaSearchableByCaller(@NonNull String packageName,
-                            @NonNull String databaseName, @NonNull String prefixedSchema,
-                            int callerUid, boolean callerHasSystemAccess) {
-                        // filter out all schema.
-                        return false;
-                    }
-                },
-                /*callerUid=*/-1,
-                /*callerHasSystemAccess=*/true);
+                new CallerAccess(/*callingPackageName=*/"otherPackageName"),
+                /*visibilityStore=*/null,
+                /*visibilityChecker=*/null);
         assertThat(nonEmptyConverter.isNothingToSearch()).isTrue();
     }
 }
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0Test.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0Test.java
new file mode 100644
index 0000000..ee371f4
--- /dev/null
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0Test.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2022 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.appsearch.localstorage.visibilitystore;
+
+import static androidx.appsearch.localstorage.visibilitystore.VisibilityStoreMigrationHelperFromV0.DEPRECATED_ACCESSIBLE_SCHEMA_PROPERTY;
+import static androidx.appsearch.localstorage.visibilitystore.VisibilityStoreMigrationHelperFromV0.DEPRECATED_NOT_DISPLAYED_BY_SYSTEM_PROPERTY;
+import static androidx.appsearch.localstorage.visibilitystore.VisibilityStoreMigrationHelperFromV0.DEPRECATED_PACKAGE_NAME_PROPERTY;
+import static androidx.appsearch.localstorage.visibilitystore.VisibilityStoreMigrationHelperFromV0.DEPRECATED_PACKAGE_SCHEMA_TYPE;
+import static androidx.appsearch.localstorage.visibilitystore.VisibilityStoreMigrationHelperFromV0.DEPRECATED_SHA_256_CERT_PROPERTY;
+import static androidx.appsearch.localstorage.visibilitystore.VisibilityStoreMigrationHelperFromV0.DEPRECATED_VISIBILITY_SCHEMA_TYPE;
+import static androidx.appsearch.localstorage.visibilitystore.VisibilityStoreMigrationHelperFromV0.DEPRECATED_VISIBLE_TO_PACKAGES_PROPERTY;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.PackageIdentifier;
+import androidx.appsearch.app.VisibilityDocument;
+import androidx.appsearch.localstorage.AppSearchImpl;
+import androidx.appsearch.localstorage.OptimizeStrategy;
+import androidx.appsearch.localstorage.UnlimitedLimitConfig;
+import androidx.appsearch.localstorage.util.PrefixUtil;
+
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.util.Collections;
+
+public class VisibilityStoreMigrationHelperFromV0Test {
+
+    /**
+     * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
+     */
+    private static final OptimizeStrategy ALWAYS_OPTIMIZE = optimizeInfo -> true;
+
+    @Rule
+    public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
+    private File mFile;
+
+    @Before
+    public void setUp() throws Exception {
+        // Give ourselves global query permissions
+        mFile = mTemporaryFolder.newFolder();
+    }
+
+    @Test
+    public void testVisibilityMigration_from0() throws Exception {
+        // Values for a "foo" client
+        String packageNameFoo = "packageFoo";
+        byte[] sha256CertFoo = new byte[32];
+
+        // Values for a "bar" client
+        String packageNameBar = "packageBar";
+        byte[] sha256CertBar = new byte[32];
+
+        // Create AppSearchImpl with visibility document version 0;
+        AppSearchImpl appSearchImplInV0 = buildAppSearchImplInV0();
+        // Build deprecated visibility documents in version 0
+        // "schema1" and "schema2" are platform hidden.
+        // "schema1" is accessible to packageFoo and "schema2" is accessible to packageBar.
+        String prefix = PrefixUtil.createPrefix("package", "database");
+        GenericDocument deprecatedVisibilityToPackageFoo = new GenericDocument.Builder<>(
+                VisibilityDocument.NAMESPACE, "", DEPRECATED_PACKAGE_SCHEMA_TYPE)
+                .setPropertyString(DEPRECATED_ACCESSIBLE_SCHEMA_PROPERTY, prefix + "Schema1")
+                .setPropertyString(DEPRECATED_PACKAGE_NAME_PROPERTY, packageNameFoo)
+                .setPropertyBytes(DEPRECATED_SHA_256_CERT_PROPERTY, sha256CertFoo)
+                .build();
+        GenericDocument deprecatedVisibilityToPackageBar = new GenericDocument.Builder<>(
+                VisibilityDocument.NAMESPACE, "", DEPRECATED_PACKAGE_SCHEMA_TYPE)
+                .setPropertyString(DEPRECATED_ACCESSIBLE_SCHEMA_PROPERTY, prefix + "Schema2")
+                .setPropertyString(DEPRECATED_PACKAGE_NAME_PROPERTY, packageNameBar)
+                .setPropertyBytes(DEPRECATED_SHA_256_CERT_PROPERTY, sha256CertBar)
+                .build();
+        GenericDocument deprecatedVisibilityDocument = new GenericDocument.Builder<>(
+                VisibilityDocument.NAMESPACE,
+                VisibilityStoreMigrationHelperFromV0.getDeprecatedVisibilityDocumentId(
+                        "package", "database"),
+                DEPRECATED_VISIBILITY_SCHEMA_TYPE)
+                .setPropertyString(DEPRECATED_NOT_DISPLAYED_BY_SYSTEM_PROPERTY,
+                        prefix + "Schema1", prefix + "Schema2")
+                .setPropertyDocument(DEPRECATED_VISIBLE_TO_PACKAGES_PROPERTY,
+                        deprecatedVisibilityToPackageFoo, deprecatedVisibilityToPackageBar)
+                .build();
+
+        // Set some client schemas into AppSearchImpl with empty VisibilityDocument since we need to
+        // directly put old version of VisibilityDocument.
+        appSearchImplInV0.setSchema(
+                "package",
+                "database",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("schema1").build(),
+                        new AppSearchSchema.Builder("schema2").build()),
+                /*prefixedVisibilityBundles=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Put deprecated visibility documents in version 0 to AppSearchImpl
+        appSearchImplInV0.putDocument(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                deprecatedVisibilityDocument,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/null);
+
+        // Persist to disk and re-open the AppSearchImpl
+        appSearchImplInV0.close();
+        AppSearchImpl appSearchImpl = AppSearchImpl.create(mFile, new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
+
+        VisibilityDocument actualDocument1 = new VisibilityDocument(
+                appSearchImpl.getDocument(
+                        VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                        VisibilityStore.VISIBILITY_DATABASE_NAME,
+                        VisibilityDocument.NAMESPACE,
+                        /*id=*/ prefix + "Schema1",
+                        /*typePropertyPaths=*/ Collections.emptyMap()));
+        VisibilityDocument actualDocument2 = new VisibilityDocument(
+                appSearchImpl.getDocument(
+                        VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                        VisibilityStore.VISIBILITY_DATABASE_NAME,
+                        VisibilityDocument.NAMESPACE,
+                        /*id=*/ prefix + "Schema2",
+                        /*typePropertyPaths=*/ Collections.emptyMap()));
+
+        VisibilityDocument expectedDocument1 =
+                new VisibilityDocument.Builder(/*id=*/ prefix + "Schema1")
+                        .setNotDisplayedBySystem(true)
+                        .setCreationTimestampMillis(actualDocument1.getCreationTimestampMillis())
+                        .addVisibleToPackage(new PackageIdentifier(packageNameFoo, sha256CertFoo))
+                        .build();
+        VisibilityDocument expectedDocument2 =
+                new VisibilityDocument.Builder(/*id=*/ prefix + "Schema2")
+                        .setNotDisplayedBySystem(true)
+                        .setCreationTimestampMillis(actualDocument2.getCreationTimestampMillis())
+                        .addVisibleToPackage(new PackageIdentifier(packageNameBar, sha256CertBar))
+                        .build();
+        assertThat(actualDocument1).isEqualTo(expectedDocument1);
+        assertThat(actualDocument2).isEqualTo(expectedDocument2);
+    }
+
+    /** Build AppSearchImpl with deprecated visibility schemas version 0.     */
+    private AppSearchImpl buildAppSearchImplInV0() throws Exception {
+        AppSearchSchema visibilityDocumentSchemaV0 = new AppSearchSchema.Builder(
+                DEPRECATED_VISIBILITY_SCHEMA_TYPE)
+                .addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
+                        DEPRECATED_NOT_DISPLAYED_BY_SYSTEM_PROPERTY)
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                        .build())
+                .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(
+                        DEPRECATED_VISIBLE_TO_PACKAGES_PROPERTY,
+                        DEPRECATED_PACKAGE_SCHEMA_TYPE)
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                        .build())
+                .build();
+        AppSearchSchema visibilityToPackagesSchemaV0 = new AppSearchSchema.Builder(
+                DEPRECATED_PACKAGE_SCHEMA_TYPE)
+                .addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
+                        DEPRECATED_PACKAGE_NAME_PROPERTY)
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                        .build())
+                .addProperty(new AppSearchSchema.BytesPropertyConfig.Builder(
+                        DEPRECATED_SHA_256_CERT_PROPERTY)
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                        .build())
+                .addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
+                        DEPRECATED_ACCESSIBLE_SCHEMA_PROPERTY)
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                        .build())
+                .build();
+        // Set deprecated visibility schema version 0 into AppSearchImpl.
+        AppSearchImpl appSearchImpl = AppSearchImpl.create(mFile, new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
+        appSearchImpl.setSchema(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                ImmutableList.of(visibilityDocumentSchemaV0, visibilityToPackagesSchemaV0),
+                /*prefixedVisibilityBundles=*/ Collections.emptyList(),
+                /*forceOverride=*/ true, // force push the old version into disk
+                /*version=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+        return appSearchImpl;
+    }
+}
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1Test.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1Test.java
new file mode 100644
index 0000000..e895ebb
--- /dev/null
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1Test.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2022 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.appsearch.localstorage.visibilitystore;
+
+import static androidx.appsearch.localstorage.visibilitystore.VisibilityStoreMigrationHelperFromV1.DEPRECATED_ROLE_ASSISTANT;
+import static androidx.appsearch.localstorage.visibilitystore.VisibilityStoreMigrationHelperFromV1.DEPRECATED_ROLE_HOME;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.PackageIdentifier;
+import androidx.appsearch.app.SetSchemaRequest;
+import androidx.appsearch.app.VisibilityDocument;
+import androidx.appsearch.localstorage.AppSearchImpl;
+import androidx.appsearch.localstorage.OptimizeStrategy;
+import androidx.appsearch.localstorage.UnlimitedLimitConfig;
+import androidx.appsearch.localstorage.util.PrefixUtil;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.util.Collections;
+
+public class VisibilityStoreMigrationHelperFromV1Test {
+
+    /**
+     * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
+     */
+    private static final OptimizeStrategy ALWAYS_OPTIMIZE = optimizeInfo -> true;
+
+    @Rule
+    public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
+    private File mFile;
+
+    @Before
+    public void setUp() throws Exception {
+        // Give ourselves global query permissions
+        mFile = mTemporaryFolder.newFolder();
+    }
+
+    @Test
+    public void testVisibilityMigration_from1() throws Exception {
+        // Values for a "foo" client
+        String packageNameFoo = "packageFoo";
+        byte[] sha256CertFoo = new byte[32];
+
+        // Values for a "bar" client
+        String packageNameBar = "packageBar";
+        byte[] sha256CertBar = new byte[32];
+
+        // Create AppSearchImpl with visibility document version 1;
+        AppSearchImpl appSearchImplInV1 = AppSearchImpl.create(mFile, new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
+        appSearchImplInV1.setSchema(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                ImmutableList.of(VisibilityDocumentV1.SCHEMA),
+                /*prefixedVisibilityBundles=*/ Collections.emptyList(),
+                /*forceOverride=*/ true, // force push the old version into disk
+                /*version=*/ 1,
+                /*setSchemaStatsBuilder=*/ null);
+        // Build deprecated visibility documents in version 1
+        String prefix = PrefixUtil.createPrefix("package", "database");
+        VisibilityDocumentV1 visibilityDocumentV1 =
+                new VisibilityDocumentV1.Builder(prefix + "Schema")
+                        .setNotDisplayedBySystem(true)
+                        .addVisibleToPackage(new PackageIdentifier(packageNameFoo, sha256CertFoo))
+                        .addVisibleToPackage(new PackageIdentifier(packageNameBar, sha256CertBar))
+                        .setVisibleToRoles(ImmutableSet.of(DEPRECATED_ROLE_HOME,
+                                DEPRECATED_ROLE_ASSISTANT))
+                        .setVisibleToPermissions(ImmutableSet.of(SetSchemaRequest.READ_SMS,
+                                SetSchemaRequest.READ_CALENDAR))
+                        .build();
+
+        // Set client schema into AppSearchImpl with empty VisibilityDocument since we need to
+        // directly put old version of VisibilityDocument.
+        appSearchImplInV1.setSchema(
+                "package",
+                "database",
+                ImmutableList.of(
+                        new AppSearchSchema.Builder("Schema").build()),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*schemaVersion=*/ 0,
+                /*setSchemaStatsBuilder=*/ null);
+
+        // Put deprecated visibility documents in version 0 to AppSearchImpl
+        appSearchImplInV1.putDocument(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                visibilityDocumentV1,
+                /*sendChangeNotifications=*/ false,
+                /*logger=*/null);
+
+        // Persist to disk and re-open the AppSearchImpl
+        appSearchImplInV1.close();
+        AppSearchImpl appSearchImpl = AppSearchImpl.create(mFile, new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
+
+        VisibilityDocument actualDocument = new VisibilityDocument(
+                appSearchImpl.getDocument(
+                        VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                        VisibilityStore.VISIBILITY_DATABASE_NAME,
+                        VisibilityDocument.NAMESPACE,
+                        /*id=*/ prefix + "Schema",
+                        /*typePropertyPaths=*/ Collections.emptyMap()));
+
+        assertThat(actualDocument.isNotDisplayedBySystem()).isTrue();
+        assertThat(actualDocument.getPackageNames()).asList().containsExactly(packageNameFoo,
+                packageNameBar);
+        assertThat(actualDocument.getSha256Certs()).isEqualTo(
+                new byte[][] {sha256CertFoo, sha256CertBar});
+        assertThat(actualDocument.getVisibleToPermissions()).containsExactlyElementsIn(
+                ImmutableSet.of(
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR),
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA),
+                        ImmutableSet.of(SetSchemaRequest.READ_ASSISTANT_APP_SEARCH_DATA)));
+    }
+}
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreTest.java
new file mode 100644
index 0000000..b1e762b
--- /dev/null
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2022 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.appsearch.localstorage.visibilitystore;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.PackageIdentifier;
+import androidx.appsearch.app.VisibilityDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import androidx.appsearch.localstorage.AppSearchImpl;
+import androidx.appsearch.localstorage.OptimizeStrategy;
+import androidx.appsearch.localstorage.UnlimitedLimitConfig;
+import androidx.appsearch.localstorage.util.PrefixUtil;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.util.Collections;
+
+public class VisibilityStoreTest {
+
+    /**
+     * Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
+     */
+    private static final OptimizeStrategy ALWAYS_OPTIMIZE = optimizeInfo -> true;
+    @Rule
+    public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
+    private File mAppSearchDir;
+    private AppSearchImpl mAppSearchImpl;
+    private VisibilityStore mVisibilityStore;
+
+    @Before
+    public void setUp() throws Exception {
+        mAppSearchDir = mTemporaryFolder.newFolder();
+        mAppSearchImpl = AppSearchImpl.create(
+                mAppSearchDir,
+                new UnlimitedLimitConfig(),
+                /*initStatsBuilder=*/ null,
+                ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
+        mVisibilityStore = new VisibilityStore(mAppSearchImpl);
+    }
+
+    @After
+    public void tearDown() {
+        mAppSearchImpl.close();
+    }
+
+    /**
+     * Make sure that we don't conflict with any special characters that AppSearchImpl has reserved.
+     */
+    @Test
+    public void testValidPackageName() {
+        assertThat(VisibilityStore.VISIBILITY_PACKAGE_NAME)
+                .doesNotContain(String.valueOf(PrefixUtil.PACKAGE_DELIMITER));
+        assertThat(VisibilityStore.VISIBILITY_PACKAGE_NAME)
+                .doesNotContain(String.valueOf(PrefixUtil.DATABASE_DELIMITER));
+    }
+
+    /**
+     * Make sure that we don't conflict with any special characters that AppSearchImpl has reserved.
+     */
+    @Test
+    public void testValidDatabaseName() {
+        assertThat(VisibilityStore.VISIBILITY_DATABASE_NAME)
+                .doesNotContain(String.valueOf(PrefixUtil.PACKAGE_DELIMITER));
+        assertThat(VisibilityStore.VISIBILITY_DATABASE_NAME)
+                .doesNotContain(String.valueOf(PrefixUtil.DATABASE_DELIMITER));
+    }
+
+    @Test
+    public void testSetAndGetVisibility() throws Exception {
+        String prefix = PrefixUtil.createPrefix("packageName", "databaseName");
+        VisibilityDocument visibilityDocument = new VisibilityDocument.Builder(prefix + "Email")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .build();
+        mVisibilityStore.setVisibility(ImmutableList.of(visibilityDocument));
+
+        assertThat(mVisibilityStore.getVisibility(prefix + "Email"))
+                .isEqualTo(visibilityDocument);
+        // Verify the VisibilityDocument is saved to AppSearchImpl.
+        VisibilityDocument actualDocument =  new VisibilityDocument(mAppSearchImpl.getDocument(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                VisibilityDocument.NAMESPACE,
+                /*id=*/ prefix + "Email",
+                /*typePropertyPaths=*/ Collections.emptyMap()));
+        assertThat(actualDocument).isEqualTo(visibilityDocument);
+    }
+
+    @Test
+    public void testRemoveVisibility() throws Exception {
+        VisibilityDocument visibilityDocument = new VisibilityDocument.Builder("Email")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .build();
+        mVisibilityStore.setVisibility(ImmutableList.of(visibilityDocument));
+
+        assertThat(mVisibilityStore.getVisibility("Email"))
+                .isEqualTo(visibilityDocument);
+        // Verify the VisibilityDocument is saved to AppSearchImpl.
+        VisibilityDocument actualDocument =  new VisibilityDocument(mAppSearchImpl.getDocument(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                VisibilityDocument.NAMESPACE,
+                /*id=*/ "Email",
+                /*typePropertyPaths=*/ Collections.emptyMap()));
+        assertThat(actualDocument).isEqualTo(visibilityDocument);
+
+        mVisibilityStore.removeVisibility(ImmutableSet.of(visibilityDocument.getId()));
+        assertThat(mVisibilityStore.getVisibility("Email")).isNull();
+        // Verify the VisibilityDocument is removed from AppSearchImpl.
+        AppSearchException e = assertThrows(AppSearchException.class,
+                () -> mAppSearchImpl.getDocument(
+                        VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                        VisibilityStore.VISIBILITY_DATABASE_NAME,
+                        VisibilityDocument.NAMESPACE,
+                        /*id=*/ "Email",
+                        /*typePropertyPaths=*/ Collections.emptyMap()));
+        assertThat(e).hasMessageThat().contains(
+                "Document (VS#Pkg$VS#Db/, Email) not found.");
+    }
+
+    @Test
+    public void testRecoverBrokenVisibilitySchema() throws Exception {
+        // Create a broken schema which could be recovered to the latest schema in a compatible
+        // change. Since we won't set force override to true to recover the broken case.
+        AppSearchSchema brokenSchema = new AppSearchSchema.Builder(VisibilityDocument.SCHEMA_TYPE)
+                .build();
+
+        // Index a broken schema into AppSearch, use the latest version to make it broken.
+        mAppSearchImpl.setSchema(
+                VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                VisibilityStore.VISIBILITY_DATABASE_NAME,
+                Collections.singletonList(brokenSchema),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ true,
+                /*version=*/ VisibilityDocument.SCHEMA_VERSION_LATEST,
+                /*setSchemaStatsBuilder=*/ null);
+        // Create VisibilityStore should recover the broken schema
+        mVisibilityStore = new VisibilityStore(mAppSearchImpl);
+
+        // We should be able to set and get Visibility settings.
+        String prefix = PrefixUtil.createPrefix("packageName", "databaseName");
+        VisibilityDocument visibilityDocument = new VisibilityDocument.Builder(prefix + "Email")
+                .setNotDisplayedBySystem(true)
+                .addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
+                .build();
+        mVisibilityStore.setVisibility(ImmutableList.of(visibilityDocument));
+
+        assertThat(mVisibilityStore.getVisibility(prefix + "Email"))
+                .isEqualTo(visibilityDocument);
+    }
+}
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AlwaysSupportedFeatures.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AlwaysSupportedFeatures.java
index 23b0e83..c7bc830 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AlwaysSupportedFeatures.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AlwaysSupportedFeatures.java
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+// @exportToFramework:copyToPath(testing/testutils/src/android/app/appsearch/testutil/external/AlwaysSupportedFeatures.java)
 package androidx.appsearch.localstorage;
 
 import androidx.annotation.NonNull;
@@ -33,7 +34,16 @@
         if (Features.SEARCH_RESULT_MATCH_INFO_SUBMATCH.equals(feature)) {
             return true;
         }
-        if (Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER.equals(feature)) {
+        if (Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK.equals(feature)) {
+            return true;
+        }
+        if (Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA.equals(feature)) {
+            return true;
+        }
+        if (Features.GLOBAL_SEARCH_SESSION_GET_BY_ID.equals(feature)) {
+            return true;
+        }
+        if (Features.ADD_PERMISSIONS_AND_GET_VISIBILITY.equals(feature)) {
             return true;
         }
         return false;
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
index a0016a2..fee5f06 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
@@ -16,6 +16,8 @@
 
 package androidx.appsearch.localstorage;
 
+import static androidx.appsearch.app.AppSearchResult.RESULT_INTERNAL_ERROR;
+import static androidx.appsearch.app.AppSearchResult.RESULT_SECURITY_ERROR;
 import static androidx.appsearch.localstorage.util.PrefixUtil.addPrefixToDocument;
 import static androidx.appsearch.localstorage.util.PrefixUtil.createPrefix;
 import static androidx.appsearch.localstorage.util.PrefixUtil.getDatabaseName;
@@ -43,6 +45,7 @@
 import androidx.appsearch.app.SearchSpec;
 import androidx.appsearch.app.SetSchemaResponse;
 import androidx.appsearch.app.StorageInfo;
+import androidx.appsearch.app.VisibilityDocument;
 import androidx.appsearch.exceptions.AppSearchException;
 import androidx.appsearch.localstorage.converter.GenericDocumentToProtoConverter;
 import androidx.appsearch.localstorage.converter.ResultCodeToProtoConverter;
@@ -58,8 +61,11 @@
 import androidx.appsearch.localstorage.stats.SearchStats;
 import androidx.appsearch.localstorage.stats.SetSchemaStats;
 import androidx.appsearch.localstorage.util.PrefixUtil;
+import androidx.appsearch.localstorage.visibilitystore.CallerAccess;
+import androidx.appsearch.localstorage.visibilitystore.VisibilityChecker;
 import androidx.appsearch.localstorage.visibilitystore.VisibilityStore;
-import androidx.appsearch.observer.AppSearchObserverCallback;
+import androidx.appsearch.localstorage.visibilitystore.VisibilityUtil;
+import androidx.appsearch.observer.ObserverCallback;
 import androidx.appsearch.observer.ObserverSpec;
 import androidx.appsearch.util.LogUtil;
 import androidx.collection.ArrayMap;
@@ -211,6 +217,21 @@
     private final ObserverManager mObserverManager = new ObserverManager();
 
     /**
+     * VisibilityStore will be used in {@link #setSchema} and {@link #getSchema} to store and query
+     * visibility information. But to create a {@link VisibilityStore}, it will call
+     * {@link #setSchema} and {@link #getSchema} to get the visibility schema. Make it nullable to
+     * avoid call it before we actually create it.
+     */
+    @Nullable
+    @VisibleForTesting
+    @GuardedBy("mReadWriteLock")
+    final VisibilityStore mVisibilityStoreLocked;
+
+    @Nullable
+    @GuardedBy("mReadWriteLock")
+    private final VisibilityChecker mVisibilityCheckerLocked;
+
+    /**
      * The counter to check when to call {@link #checkForOptimize}. The
      * interval is
      * {@link #CHECK_OPTIMIZE_INTERVAL}.
@@ -234,15 +255,20 @@
      * and putDocument.
      *
      * @param initStatsBuilder collects stats for initialization if provided.
+     * @param visibilityChecker The {@link VisibilityChecker} that check whether the caller has
+     *                          access to aa specific schema. Pass null will lost that ability and
+     *                          global querier could only get their own data.
      */
     @NonNull
     public static AppSearchImpl create(
             @NonNull File icingDir,
             @NonNull LimitConfig limitConfig,
             @Nullable InitializeStats.Builder initStatsBuilder,
-            @NonNull OptimizeStrategy optimizeStrategy)
+            @NonNull OptimizeStrategy optimizeStrategy,
+            @Nullable VisibilityChecker visibilityChecker)
             throws AppSearchException {
-        return new AppSearchImpl(icingDir, limitConfig, initStatsBuilder, optimizeStrategy);
+        return new AppSearchImpl(icingDir, limitConfig, initStatsBuilder, optimizeStrategy,
+                visibilityChecker);
     }
 
     /**
@@ -252,11 +278,13 @@
             @NonNull File icingDir,
             @NonNull LimitConfig limitConfig,
             @Nullable InitializeStats.Builder initStatsBuilder,
-            @NonNull OptimizeStrategy optimizeStrategy)
+            @NonNull OptimizeStrategy optimizeStrategy,
+            @Nullable VisibilityChecker visibilityChecker)
             throws AppSearchException {
         Preconditions.checkNotNull(icingDir);
         mLimitConfig = Preconditions.checkNotNull(limitConfig);
         mOptimizeStrategy = Preconditions.checkNotNull(optimizeStrategy);
+        mVisibilityCheckerLocked = visibilityChecker;
 
         mReadWriteLock.writeLock().lock();
         try {
@@ -355,6 +383,14 @@
                 resetLocked(initStatsBuilder);
             }
 
+            long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime();
+            mVisibilityStoreLocked = new VisibilityStore(this);
+            long prepareVisibilityStoreLatencyEndMillis = SystemClock.elapsedRealtime();
+            if (initStatsBuilder != null) {
+                initStatsBuilder.setPrepareVisibilityStoreLatencyMillis((int)
+                        (prepareVisibilityStoreLatencyEndMillis
+                                - prepareVisibilityStoreLatencyStartMillis));
+            }
         } finally {
             mReadWriteLock.writeLock().unlock();
         }
@@ -397,21 +433,21 @@
      *
      * <p>This method belongs to mutate group.
      *
-     * @param packageName                   The package name that owns the schemas.
-     * @param databaseName                  The name of the database where this schema lives.
-     * @param schemas                       Schemas to set for this app.
-     * @param visibilityStore               If set, {@code schemasNotDisplayedBySystem} and {@code
-     *                                      schemasVisibleToPackages} will be saved here if the
-     *                                      schema is successfully applied.
-     * @param schemasNotDisplayedBySystem   Schema types that should not be surfaced on platform
-     *                                      surfaces.
-     * @param schemasVisibleToPackages      Schema types that are visible to the specified packages.
-     * @param forceOverride                 Whether to force-apply the schema even if it is
-     *                                      incompatible. Documents
-     *                                      which do not comply with the new schema will be deleted.
-     * @param version                       The overall version number of the request.
-     * @param setSchemaStatsBuilder         Builder for {@link SetSchemaStats} to hold stats for
-     *                                      setSchema
+     * @param packageName                 The package name that owns the schemas.
+     * @param databaseName                The name of the database where this schema lives.
+     * @param schemas                     Schemas to set for this app.
+     * @param visibilityDocuments         {@link VisibilityDocument}s that contain all
+     *                                    visibility setting information for those schemas
+     *                                    has user custom settings. Other schemas in the list
+     *                                    that don't has a {@link VisibilityDocument}
+     *                                    will be treated as having the default visibility,
+     *                                    which is accessible by the system and no other packages.
+     * @param forceOverride               Whether to force-apply the schema even if it is
+     *                                    incompatible. Documents
+     *                                    which do not comply with the new schema will be deleted.
+     * @param version                     The overall version number of the request.
+     * @param setSchemaStatsBuilder       Builder for {@link SetSchemaStats} to hold stats for
+     *                                    setSchema
      * @return The response contains deleted schema types and incompatible schema types of this
      * call.
      * @throws AppSearchException On IcingSearchEngine error. If the status code is
@@ -423,160 +459,400 @@
             @NonNull String packageName,
             @NonNull String databaseName,
             @NonNull List<AppSearchSchema> schemas,
-            @Nullable VisibilityStore visibilityStore,
-            @NonNull List<String> schemasNotDisplayedBySystem,
-            @NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages,
+            @NonNull List<VisibilityDocument> visibilityDocuments,
             boolean forceOverride,
             int version,
             @Nullable SetSchemaStats.Builder setSchemaStatsBuilder) throws AppSearchException {
         mReadWriteLock.writeLock().lock();
         try {
             throwIfClosedLocked();
-
-            SchemaProto.Builder existingSchemaBuilder = getSchemaProtoLocked().toBuilder();
-
-            SchemaProto.Builder newSchemaBuilder = SchemaProto.newBuilder();
-            for (int i = 0; i < schemas.size(); i++) {
-                AppSearchSchema schema = schemas.get(i);
-                SchemaTypeConfigProto schemaTypeProto =
-                        SchemaToProtoConverter.toSchemaTypeConfigProto(schema, version);
-                newSchemaBuilder.addTypes(schemaTypeProto);
-            }
-
-            String prefix = createPrefix(packageName, databaseName);
-            // Combine the existing schema (which may have types from other prefixes) with this
-            // prefix's new schema. Modifies the existingSchemaBuilder.
-            RewrittenSchemaResults rewrittenSchemaResults = rewriteSchema(prefix,
-                    existingSchemaBuilder,
-                    newSchemaBuilder.build());
-
-            // Apply schema
-            SchemaProto finalSchema = existingSchemaBuilder.build();
-            mLogUtil.piiTrace("setSchema, request", finalSchema.getTypesCount(), finalSchema);
-            SetSchemaResultProto setSchemaResultProto =
-                    mIcingSearchEngineLocked.setSchema(finalSchema, forceOverride);
-            mLogUtil.piiTrace(
-                    "setSchema, response", setSchemaResultProto.getStatus(), setSchemaResultProto);
-
-            if (setSchemaStatsBuilder != null) {
-                setSchemaStatsBuilder.setStatusCode(statusProtoToResultCode(
-                        setSchemaResultProto.getStatus()));
-                AppSearchLoggerHelper.copyNativeStats(setSchemaResultProto,
-                        setSchemaStatsBuilder);
-            }
-
-            // Determine whether it succeeded.
-            try {
-                checkSuccess(setSchemaResultProto.getStatus());
-            } catch (AppSearchException e) {
-                // Swallow the exception for the incompatible change case. We will propagate
-                // those deleted schemas and incompatible types to the SetSchemaResponse.
-                boolean isFailedPrecondition = setSchemaResultProto.getStatus().getCode()
-                        == StatusProto.Code.FAILED_PRECONDITION;
-                boolean isIncompatible = setSchemaResultProto.getDeletedSchemaTypesCount() > 0
-                        || setSchemaResultProto.getIncompatibleSchemaTypesCount() > 0;
-                if (isFailedPrecondition && isIncompatible) {
-                    return SetSchemaResponseToProtoConverter
-                            .toSetSchemaResponse(setSchemaResultProto, prefix);
-                } else {
-                    throw e;
-                }
-            }
-
-            // Update derived data structures.
-            for (SchemaTypeConfigProto schemaTypeConfigProto :
-                    rewrittenSchemaResults.mRewrittenPrefixedTypes.values()) {
-                addToMap(mSchemaMapLocked, prefix, schemaTypeConfigProto);
-            }
-
-            for (String schemaType : rewrittenSchemaResults.mDeletedPrefixedTypes) {
-                removeFromMap(mSchemaMapLocked, prefix, schemaType);
-            }
-
-            if (visibilityStore != null) {
-                Set<String> prefixedSchemasNotDisplayedBySystem =
-                        new ArraySet<>(schemasNotDisplayedBySystem.size());
-                for (int i = 0; i < schemasNotDisplayedBySystem.size(); i++) {
-                    prefixedSchemasNotDisplayedBySystem.add(
-                            prefix + schemasNotDisplayedBySystem.get(i));
-                }
-
-                Map<String, List<PackageIdentifier>> prefixedSchemasVisibleToPackages =
-                        new ArrayMap<>(schemasVisibleToPackages.size());
-                for (Map.Entry<String, List<PackageIdentifier>> entry
-                        : schemasVisibleToPackages.entrySet()) {
-                    prefixedSchemasVisibleToPackages.put(prefix + entry.getKey(), entry.getValue());
-                }
-
-                visibilityStore.setVisibility(
+            if (mObserverManager.isPackageObserved(packageName)) {
+                return doSetSchemaWithChangeNotificationLocked(
                         packageName,
                         databaseName,
-                        prefixedSchemasNotDisplayedBySystem,
-                        prefixedSchemasVisibleToPackages);
+                        schemas,
+                        visibilityDocuments,
+                        forceOverride,
+                        version,
+                        setSchemaStatsBuilder);
+            } else {
+                return doSetSchemaNoChangeNotificationLocked(
+                        packageName,
+                        databaseName,
+                        schemas,
+                        visibilityDocuments,
+                        forceOverride,
+                        version,
+                        setSchemaStatsBuilder);
             }
-
-            return SetSchemaResponseToProtoConverter
-                    .toSetSchemaResponse(setSchemaResultProto, prefix);
         } finally {
             mReadWriteLock.writeLock().unlock();
         }
     }
 
     /**
+     * Updates the AppSearch schema for this app, dispatching change notifications.
+     *
+     * @see #setSchema
+     * @see #doSetSchemaNoChangeNotificationLocked
+     */
+    @GuardedBy("mReadWriteLock")
+    @NonNull
+    private SetSchemaResponse doSetSchemaWithChangeNotificationLocked(
+            @NonNull String packageName,
+            @NonNull String databaseName,
+            @NonNull List<AppSearchSchema> schemas,
+            @NonNull List<VisibilityDocument> visibilityDocuments,
+            boolean forceOverride,
+            int version,
+            @Nullable SetSchemaStats.Builder setSchemaStatsBuilder) throws AppSearchException {
+        // First, capture the old state of the system. This includes the old schema as well as
+        // whether each registered observer can access each type. Once VisibilityStore is updated
+        // by the setSchema call, the information of which observers could see which types will be
+        // lost.
+        GetSchemaResponse oldSchema = getSchema(
+                packageName,
+                databaseName,
+                // A CallerAccess object for internal use that has local access to this database.
+                new CallerAccess(/*callingPackageName=*/packageName));
+
+        // Cache some lookup tables to help us work with the old schema
+        Set<AppSearchSchema> oldSchemaTypes = oldSchema.getSchemas();
+        Map<String, AppSearchSchema> oldSchemaNameToType = new ArrayMap<>(oldSchemaTypes.size());
+        // Maps unprefixed schema name to the set of listening packages that had visibility into
+        // that type under the old schema.
+        Map<String, Set<String>> oldSchemaNameToVisibleListeningPackage =
+                new ArrayMap<>(oldSchemaTypes.size());
+        for (AppSearchSchema oldSchemaType : oldSchemaTypes) {
+            String oldSchemaName = oldSchemaType.getSchemaType();
+            oldSchemaNameToType.put(oldSchemaName, oldSchemaType);
+            oldSchemaNameToVisibleListeningPackage.put(
+                    oldSchemaName,
+                    mObserverManager.getObserversForSchemaType(
+                            packageName,
+                            databaseName,
+                            oldSchemaName,
+                            mVisibilityStoreLocked,
+                            mVisibilityCheckerLocked));
+        }
+
+        // Apply the new schema
+        SetSchemaResponse setSchemaResponse = doSetSchemaNoChangeNotificationLocked(
+                packageName,
+                databaseName,
+                schemas,
+                visibilityDocuments,
+                forceOverride,
+                version,
+                setSchemaStatsBuilder);
+
+        // This check is needed wherever setSchema is called to detect soft errors which do not
+        // throw an exception but also prevent the schema from actually being applied.
+        // TODO(b/229874420): Improve the usability of doSetSchemaNoChangeNotificationLocked() by
+        //  adding documentation that the return value must be checked for these conditions, and by
+        //  making it easier to check for these conditions via one of the ways documented in the
+        //  bug.
+        if (!forceOverride && (
+                !setSchemaResponse.getDeletedTypes().isEmpty()
+                        || !setSchemaResponse.getIncompatibleTypes().isEmpty())
+        ) {
+            return setSchemaResponse;
+        }
+
+        // Cache some lookup tables to help us work with the new schema
+        Map<String, AppSearchSchema> newSchemaNameToType = new ArrayMap<>(schemas.size());
+        // Maps unprefixed schema name to the set of listening packages that have visibility into
+        // that type under the new schema.
+        Map<String, Set<String>> newSchemaNameToVisibleListeningPackage =
+                new ArrayMap<>(schemas.size());
+        for (AppSearchSchema newSchemaType : schemas) {
+            String newSchemaName = newSchemaType.getSchemaType();
+            newSchemaNameToType.put(newSchemaName, newSchemaType);
+            newSchemaNameToVisibleListeningPackage.put(
+                    newSchemaName,
+                    mObserverManager.getObserversForSchemaType(
+                            packageName,
+                            databaseName,
+                            newSchemaName,
+                            mVisibilityStoreLocked,
+                            mVisibilityCheckerLocked));
+        }
+
+        // Create a unified set of all schema names mentioned in either the old or new schema.
+        Set<String> allSchemaNames = new ArraySet<>(oldSchemaNameToType.keySet());
+        allSchemaNames.addAll(newSchemaNameToType.keySet());
+
+        // Perform the diff between the old and new schema.
+        for (String schemaName : allSchemaNames) {
+            final AppSearchSchema contentBefore = oldSchemaNameToType.get(schemaName);
+            final AppSearchSchema contentAfter = newSchemaNameToType.get(schemaName);
+
+            final boolean existBefore = (contentBefore != null);
+            final boolean existAfter = (contentAfter != null);
+
+            // This should never happen
+            if (!existBefore && !existAfter) {
+                continue;
+            }
+
+            boolean contentsChanged = true;
+            if (existBefore && existAfter && contentBefore.equals(contentAfter)) {
+                contentsChanged = false;
+            }
+
+            Set<String> oldVisibleListeners =
+                    oldSchemaNameToVisibleListeningPackage.get(schemaName);
+            Set<String> newVisibleListeners =
+                    newSchemaNameToVisibleListeningPackage.get(schemaName);
+            Set<String> allListeningPackages = new ArraySet<>(oldVisibleListeners);
+            if (newVisibleListeners != null) {
+                allListeningPackages.addAll(newVisibleListeners);
+            }
+
+            // Now that we've computed the relationship between the old and new schema, we go
+            // observer by observer and consider the observer's own personal view of the schema.
+            for (String listeningPackageName : allListeningPackages) {
+                // Figure out the visibility
+                final boolean visibleBefore = (
+                        existBefore
+                                && oldVisibleListeners != null
+                                && oldVisibleListeners.contains(listeningPackageName));
+                final boolean visibleAfter = (
+                        existAfter
+                                && newVisibleListeners != null
+                                && newVisibleListeners.contains(listeningPackageName));
+
+                // Now go through the truth table of all the relevant flags.
+                // visibleBefore and visibleAfter take into account existBefore and existAfter, so
+                // we can stop worrying about existBefore and existAfter.
+                boolean sendNotification = false;
+                if (visibleBefore && visibleAfter && contentsChanged) {
+                    sendNotification = true;  // Type configuration was modified
+                } else if (!visibleBefore && visibleAfter) {
+                    sendNotification = true;  // Newly granted visibility or type was created
+                } else if (visibleBefore && !visibleAfter) {
+                    sendNotification = true;  // Revoked visibility or type was deleted
+                } else {
+                    // No visibility before and no visibility after. Nothing to dispatch.
+                }
+
+                if (sendNotification) {
+                    mObserverManager.onSchemaChange(
+                            /*listeningPackageName=*/listeningPackageName,
+                            /*targetPackageName=*/packageName,
+                            /*databaseName=*/databaseName,
+                            /*schemaName=*/schemaName);
+                }
+            }
+        }
+
+        return setSchemaResponse;
+    }
+
+    /**
+     * Updates the AppSearch schema for this app, without dispatching change notifications.
+     *
+     * <p>This method can be used only when no one is observing {@code packageName}.
+     *
+     * @see #setSchema
+     * @see #doSetSchemaWithChangeNotificationLocked
+     */
+    @GuardedBy("mReadWriteLock")
+    @NonNull
+    private SetSchemaResponse doSetSchemaNoChangeNotificationLocked(
+            @NonNull String packageName,
+            @NonNull String databaseName,
+            @NonNull List<AppSearchSchema> schemas,
+            @NonNull List<VisibilityDocument> visibilityDocuments,
+            boolean forceOverride,
+            int version,
+            @Nullable SetSchemaStats.Builder setSchemaStatsBuilder) throws AppSearchException {
+        SchemaProto.Builder existingSchemaBuilder = getSchemaProtoLocked().toBuilder();
+
+        SchemaProto.Builder newSchemaBuilder = SchemaProto.newBuilder();
+        for (int i = 0; i < schemas.size(); i++) {
+            AppSearchSchema schema = schemas.get(i);
+            SchemaTypeConfigProto schemaTypeProto =
+                    SchemaToProtoConverter.toSchemaTypeConfigProto(schema, version);
+            newSchemaBuilder.addTypes(schemaTypeProto);
+        }
+
+        String prefix = createPrefix(packageName, databaseName);
+        // Combine the existing schema (which may have types from other prefixes) with this
+        // prefix's new schema. Modifies the existingSchemaBuilder.
+        RewrittenSchemaResults rewrittenSchemaResults = rewriteSchema(prefix,
+                existingSchemaBuilder,
+                newSchemaBuilder.build());
+
+        // Apply schema
+        SchemaProto finalSchema = existingSchemaBuilder.build();
+        mLogUtil.piiTrace("setSchema, request", finalSchema.getTypesCount(), finalSchema);
+        SetSchemaResultProto setSchemaResultProto =
+                mIcingSearchEngineLocked.setSchema(finalSchema, forceOverride);
+        mLogUtil.piiTrace(
+                "setSchema, response", setSchemaResultProto.getStatus(), setSchemaResultProto);
+
+        if (setSchemaStatsBuilder != null) {
+            setSchemaStatsBuilder.setStatusCode(statusProtoToResultCode(
+                    setSchemaResultProto.getStatus()));
+            AppSearchLoggerHelper.copyNativeStats(setSchemaResultProto,
+                    setSchemaStatsBuilder);
+        }
+
+        // Determine whether it succeeded.
+        try {
+            checkSuccess(setSchemaResultProto.getStatus());
+        } catch (AppSearchException e) {
+            // Swallow the exception for the incompatible change case. We will propagate
+            // those deleted schemas and incompatible types to the SetSchemaResponse.
+            boolean isFailedPrecondition = setSchemaResultProto.getStatus().getCode()
+                    == StatusProto.Code.FAILED_PRECONDITION;
+            boolean isIncompatible = setSchemaResultProto.getDeletedSchemaTypesCount() > 0
+                    || setSchemaResultProto.getIncompatibleSchemaTypesCount() > 0;
+            if (isFailedPrecondition && isIncompatible) {
+                return SetSchemaResponseToProtoConverter
+                        .toSetSchemaResponse(setSchemaResultProto, prefix);
+            } else {
+                throw e;
+            }
+        }
+
+        // Update derived data structures.
+        for (SchemaTypeConfigProto schemaTypeConfigProto :
+                rewrittenSchemaResults.mRewrittenPrefixedTypes.values()) {
+            addToMap(mSchemaMapLocked, prefix, schemaTypeConfigProto);
+        }
+
+        for (String schemaType : rewrittenSchemaResults.mDeletedPrefixedTypes) {
+            removeFromMap(mSchemaMapLocked, prefix, schemaType);
+        }
+        // Since the constructor of VisibilityStore will set schema. Avoid call visibility
+        // store before we have already created it.
+        if (mVisibilityStoreLocked != null) {
+            // Add prefix to all visibility documents.
+            List<VisibilityDocument> prefixedVisibilityDocuments =
+                    new ArrayList<>(visibilityDocuments.size());
+            // Find out which Visibility document is deleted or changed to all-default settings.
+            // We need to remove them from Visibility Store.
+            Set<String> deprecatedVisibilityDocuments =
+                    new ArraySet<>(rewrittenSchemaResults.mRewrittenPrefixedTypes.keySet());
+            for (int i = 0; i < visibilityDocuments.size(); i++) {
+                VisibilityDocument unPrefixedDocument = visibilityDocuments.get(i);
+                // The VisibilityDocument is controlled by the client and it's untrusted but we
+                // make it safe by appending a prefix.
+                // We must control the package-database prefix. Therefore even if the client
+                // fake the id, they can only mess their own app. That's totally allowed and
+                // they can do this via the public API too.
+                String prefixedSchemaType = prefix + unPrefixedDocument.getId();
+                prefixedVisibilityDocuments.add(new VisibilityDocument(
+                        unPrefixedDocument.toBuilder()
+                                .setId(prefixedSchemaType)
+                                .build()));
+                // This schema has visibility settings. We should keep it from the removal list.
+                deprecatedVisibilityDocuments.remove(prefixedSchemaType);
+            }
+            // Now deprecatedVisibilityDocuments contains those existing schemas that has
+            // all-default visibility settings, add deleted schemas. That's all we need to
+            // remove.
+            deprecatedVisibilityDocuments.addAll(rewrittenSchemaResults.mDeletedPrefixedTypes);
+            mVisibilityStoreLocked.removeVisibility(deprecatedVisibilityDocuments);
+            mVisibilityStoreLocked.setVisibility(prefixedVisibilityDocuments);
+        }
+        return SetSchemaResponseToProtoConverter
+                .toSetSchemaResponse(setSchemaResultProto, prefix);
+    }
+
+    /**
      * Retrieves the AppSearch schema for this package name, database.
      *
      * <p>This method belongs to query group.
      *
-     * @param packageName  Package name that owns this schema
-     * @param databaseName The name of the database where this schema lives.
+     * @param packageName  Package that owns the requested {@link AppSearchSchema} instances.
+     * @param databaseName Database that owns the requested {@link AppSearchSchema} instances.
+     * @param callerAccess Visibility access info of the calling app
      * @throws AppSearchException on IcingSearchEngine error.
      */
     @NonNull
-    public GetSchemaResponse getSchema(@NonNull String packageName,
-            @NonNull String databaseName) throws AppSearchException {
+    public GetSchemaResponse getSchema(
+            @NonNull String packageName,
+            @NonNull String databaseName,
+            @NonNull CallerAccess callerAccess)
+            throws AppSearchException {
         mReadWriteLock.readLock().lock();
         try {
             throwIfClosedLocked();
 
             SchemaProto fullSchema = getSchemaProtoLocked();
-
             String prefix = createPrefix(packageName, databaseName);
             GetSchemaResponse.Builder responseBuilder = new GetSchemaResponse.Builder();
             for (int i = 0; i < fullSchema.getTypesCount(); i++) {
-                String typePrefix = getPrefix(fullSchema.getTypes(i).getSchemaType());
+                // Check that this type belongs to the requested app and that the caller has
+                // access to it.
+                SchemaTypeConfigProto typeConfig = fullSchema.getTypes(i);
+                String prefixedSchemaType = typeConfig.getSchemaType();
+                String typePrefix = getPrefix(prefixedSchemaType);
                 if (!prefix.equals(typePrefix)) {
+                    // This schema type doesn't belong to the database we're querying for.
                     continue;
                 }
-                // Rewrite SchemaProto.types.schema_type
-                SchemaTypeConfigProto.Builder typeConfigBuilder = fullSchema.getTypes(
-                        i).toBuilder();
-                String newSchemaType =
-                        typeConfigBuilder.getSchemaType().substring(prefix.length());
-                typeConfigBuilder.setSchemaType(newSchemaType);
-
-                // Rewrite SchemaProto.types.properties.schema_type
-                for (int propertyIdx = 0;
-                        propertyIdx < typeConfigBuilder.getPropertiesCount();
-                        propertyIdx++) {
-                    PropertyConfigProto.Builder propertyConfigBuilder =
-                            typeConfigBuilder.getProperties(propertyIdx).toBuilder();
-                    if (!propertyConfigBuilder.getSchemaType().isEmpty()) {
-                        String newPropertySchemaType = propertyConfigBuilder.getSchemaType()
-                                .substring(prefix.length());
-                        propertyConfigBuilder.setSchemaType(newPropertySchemaType);
-                        typeConfigBuilder.setProperties(propertyIdx, propertyConfigBuilder);
-                    }
+                if (!VisibilityUtil.isSchemaSearchableByCaller(
+                        callerAccess,
+                        packageName,
+                        prefixedSchemaType,
+                        mVisibilityStoreLocked,
+                        mVisibilityCheckerLocked)) {
+                    // Caller doesn't have access to this type.
+                    continue;
                 }
 
+                // Rewrite SchemaProto.types.schema_type
+                SchemaTypeConfigProto.Builder typeConfigBuilder = typeConfig.toBuilder();
+                PrefixUtil.removePrefixesFromSchemaType(typeConfigBuilder);
                 AppSearchSchema schema = SchemaToProtoConverter.toAppSearchSchema(
                         typeConfigBuilder);
 
                 //TODO(b/183050495) find a place to store the version for the database, rather
                 // than read from a schema.
-                responseBuilder.setVersion(fullSchema.getTypes(i).getVersion());
+                responseBuilder.setVersion(typeConfig.getVersion());
                 responseBuilder.addSchema(schema);
+
+                // Populate visibility info. Since the constructor of VisibilityStore will get
+                // schema. Avoid call visibility store before we have already created it.
+                if (mVisibilityStoreLocked != null) {
+                    String typeName = typeConfig.getSchemaType().substring(typePrefix.length());
+                    VisibilityDocument visibilityDocument =
+                            mVisibilityStoreLocked.getVisibility(prefixedSchemaType);
+                    if (visibilityDocument != null) {
+                        if (visibilityDocument.isNotDisplayedBySystem()) {
+                            responseBuilder
+                                    .addSchemaTypeNotDisplayedBySystem(typeName);
+                        }
+                        String[] packageNames = visibilityDocument.getPackageNames();
+                        byte[][] sha256Certs = visibilityDocument.getSha256Certs();
+                        if (packageNames.length != sha256Certs.length) {
+                            throw new AppSearchException(RESULT_INTERNAL_ERROR,
+                                    "The length of package names and sha256Crets are different!");
+                        }
+                        if (packageNames.length != 0) {
+                            Set<PackageIdentifier> packageIdentifier = new ArraySet<>();
+                            for (int j = 0; j < packageNames.length; j++) {
+                                packageIdentifier.add(new PackageIdentifier(
+                                        packageNames[j], sha256Certs[j]));
+                            }
+                            responseBuilder.setSchemaTypeVisibleToPackages(typeName,
+                                    packageIdentifier);
+                        }
+                        Set<Set<Integer>> visibleToPermissions =
+                                visibilityDocument.getVisibleToPermissions();
+                        if (visibleToPermissions != null) {
+                            responseBuilder.setRequiredPermissionsForSchemaTypeVisibility(
+                                    typeName,  visibleToPermissions);
+                        }
+                    }
+                }
             }
             return responseBuilder.build();
+
         } finally {
             mReadWriteLock.readLock().unlock();
         }
@@ -627,13 +903,20 @@
      *
      * <p>This method belongs to mutate group.
      *
-     * @param packageName  The package name that owns this document.
-     * @param databaseName The databaseName this document resides in.
-     * @param document     The document to index.
+     * @param packageName             The package name that owns this document.
+     * @param databaseName            The databaseName this document resides in.
+     * @param document                The document to index.
+     * @param sendChangeNotifications Whether to dispatch
+     *                                {@link androidx.appsearch.observer.DocumentChangeInfo}
+     *                                messages to observers for this change.
      * @throws AppSearchException on IcingSearchEngine error.
      */
-    public void putDocument(@NonNull String packageName, @NonNull String databaseName,
-            @NonNull GenericDocument document, @Nullable AppSearchLogger logger)
+    public void putDocument(
+            @NonNull String packageName,
+            @NonNull String databaseName,
+            @NonNull GenericDocument document,
+            boolean sendChangeNotifications,
+            @Nullable AppSearchLogger logger)
             throws AppSearchException {
         PutDocumentStats.Builder pStatsBuilder = null;
         if (logger != null) {
@@ -688,8 +971,16 @@
             checkSuccess(putResultProto.getStatus());
 
             // Prepare notifications
-            mObserverManager.onDocumentChange(
-                    packageName, databaseName, document.getNamespace(), document.getSchemaType());
+            if (sendChangeNotifications) {
+                mObserverManager.onDocumentChange(
+                        packageName,
+                        databaseName,
+                        document.getNamespace(),
+                        document.getSchemaType(),
+                        document.getId(),
+                        mVisibilityStoreLocked,
+                        mVisibilityCheckerLocked);
+            }
         } finally {
             mReadWriteLock.writeLock().unlock();
 
@@ -758,6 +1049,67 @@
     }
 
     /**
+     * Retrieves a document from the AppSearch index by namespace and document ID from any
+     * application the caller is allowed to view
+     *
+     * <p>This method will handle both Icing engine errors as well as permission errors by
+     * throwing an obfuscated RESULT_NOT_FOUND exception. This is done so the caller doesn't
+     * receive information on whether or not a file they are not allowed to access exists or not.
+     * This is different from the behavior of {@link #getDocument}.
+     *
+     * @param packageName       The package that owns this document.
+     * @param databaseName      The databaseName this document resides in.
+     * @param namespace         The namespace this document resides in.
+     * @param id                The ID of the document to get.
+     * @param typePropertyPaths A map of schema type to a list of property paths to return in the
+     *                          result.
+     * @param callerAccess      Visibility access info of the calling app
+     * @return The Document contents
+     * @throws AppSearchException on IcingSearchEngine error or invalid permissions
+     */
+    @NonNull
+    public GenericDocument globalGetDocument(
+            @NonNull String packageName,
+            @NonNull String databaseName,
+            @NonNull String namespace,
+            @NonNull String id,
+            @NonNull Map<String, List<String>> typePropertyPaths,
+            @NonNull CallerAccess callerAccess) throws AppSearchException {
+        mReadWriteLock.readLock().lock();
+        try {
+            throwIfClosedLocked();
+            // We retrieve the document before checking for access, as we do not know which
+            // schema the document is under. Schema is required for checking access
+            DocumentProto documentProto;
+            try {
+                documentProto = getDocumentProtoByIdLocked(packageName, databaseName,
+                        namespace, id, typePropertyPaths);
+
+                if (!VisibilityUtil.isSchemaSearchableByCaller(
+                        callerAccess,
+                        packageName,
+                        documentProto.getSchema(),
+                        mVisibilityStoreLocked,
+                        mVisibilityCheckerLocked)) {
+                    throw new AppSearchException(AppSearchResult.RESULT_NOT_FOUND);
+                }
+            } catch (AppSearchException e) {
+                throw new AppSearchException(AppSearchResult.RESULT_NOT_FOUND,
+                        "Document (" + namespace + ", " + id + ") not found.");
+            }
+
+            DocumentProto.Builder documentBuilder = documentProto.toBuilder();
+            removePrefixesFromDocument(documentBuilder);
+            String prefix = createPrefix(packageName, databaseName);
+            Map<String, SchemaTypeConfigProto> schemaTypeMap = mSchemaMapLocked.get(prefix);
+            return GenericDocumentToProtoConverter.toGenericDocument(documentBuilder.build(),
+                    prefix, schemaTypeMap);
+        } finally {
+            mReadWriteLock.readLock().unlock();
+        }
+    }
+
+    /**
      * Retrieves a document from the AppSearch index by namespace and document ID.
      *
      * <p>This method belongs to query group.
@@ -773,47 +1125,24 @@
      */
     @NonNull
     public GenericDocument getDocument(
-            @NonNull String packageName, @NonNull String databaseName,
+            @NonNull String packageName,
+            @NonNull String databaseName,
             @NonNull String namespace,
             @NonNull String id,
             @NonNull Map<String, List<String>> typePropertyPaths) throws AppSearchException {
         mReadWriteLock.readLock().lock();
         try {
             throwIfClosedLocked();
+            DocumentProto documentProto = getDocumentProtoByIdLocked(packageName, databaseName,
+                    namespace, id, typePropertyPaths);
+            DocumentProto.Builder documentBuilder = documentProto.toBuilder();
+            removePrefixesFromDocument(documentBuilder);
+
             String prefix = createPrefix(packageName, databaseName);
-            List<TypePropertyMask.Builder> nonPrefixedPropertyMaskBuilders =
-                    TypePropertyPathToProtoConverter
-                            .toTypePropertyMaskBuilderList(typePropertyPaths);
-            List<TypePropertyMask> prefixedPropertyMasks =
-                    new ArrayList<>(nonPrefixedPropertyMaskBuilders.size());
-            for (int i = 0; i < nonPrefixedPropertyMaskBuilders.size(); ++i) {
-                String nonPrefixedType = nonPrefixedPropertyMaskBuilders.get(i).getSchemaType();
-                String prefixedType = nonPrefixedType.equals(
-                        GetByDocumentIdRequest.PROJECTION_SCHEMA_TYPE_WILDCARD)
-                        ? nonPrefixedType : prefix + nonPrefixedType;
-                prefixedPropertyMasks.add(
-                        nonPrefixedPropertyMaskBuilders.get(i).setSchemaType(prefixedType).build());
-            }
-            GetResultSpecProto getResultSpec =
-                    GetResultSpecProto.newBuilder().addAllTypePropertyMasks(prefixedPropertyMasks)
-                            .build();
-
-            String finalNamespace = createPrefix(packageName, databaseName) + namespace;
-            if (mLogUtil.isPiiTraceEnabled()) {
-                mLogUtil.piiTrace(
-                        "getDocument, request", finalNamespace + ", " + id + "," + getResultSpec);
-            }
-            GetResultProto getResultProto =
-                    mIcingSearchEngineLocked.get(finalNamespace, id, getResultSpec);
-            mLogUtil.piiTrace("getDocument, response", getResultProto.getStatus(), getResultProto);
-            checkSuccess(getResultProto.getStatus());
-
             // The schema type map cannot be null at this point. It could only be null if no
             // schema had ever been set for that prefix. Given we have retrieved a document from
             // the index, we know a schema had to have been set.
             Map<String, SchemaTypeConfigProto> schemaTypeMap = mSchemaMapLocked.get(prefix);
-            DocumentProto.Builder documentBuilder = getResultProto.getDocument().toBuilder();
-            removePrefixesFromDocument(documentBuilder);
             return GenericDocumentToProtoConverter.toGenericDocument(documentBuilder.build(),
                     prefix, schemaTypeMap);
         } finally {
@@ -822,6 +1151,58 @@
     }
 
     /**
+     * Returns a DocumentProto from Icing.
+     *
+     * @param packageName       The package that owns this document.
+     * @param databaseName      The databaseName this document resides in.
+     * @param namespace         The namespace this document resides in.
+     * @param id                The ID of the document to get.
+     * @param typePropertyPaths A map of schema type to a list of property paths to return in the
+     *                          result.
+     * @return the DocumentProto object
+     * @throws AppSearchException on IcingSearchEngine error
+     */
+    @NonNull
+    @GuardedBy("mReadWriteLock")
+    private DocumentProto getDocumentProtoByIdLocked(
+            @NonNull String packageName,
+            @NonNull String databaseName,
+            @NonNull String namespace,
+            @NonNull String id,
+            @NonNull Map<String, List<String>> typePropertyPaths)
+            throws AppSearchException {
+        String prefix = createPrefix(packageName, databaseName);
+        List<TypePropertyMask.Builder> nonPrefixedPropertyMaskBuilders =
+                TypePropertyPathToProtoConverter
+                        .toTypePropertyMaskBuilderList(typePropertyPaths);
+        List<TypePropertyMask> prefixedPropertyMasks =
+                new ArrayList<>(nonPrefixedPropertyMaskBuilders.size());
+        for (int i = 0; i < nonPrefixedPropertyMaskBuilders.size(); ++i) {
+            String nonPrefixedType = nonPrefixedPropertyMaskBuilders.get(i).getSchemaType();
+            String prefixedType = nonPrefixedType.equals(
+                    GetByDocumentIdRequest.PROJECTION_SCHEMA_TYPE_WILDCARD)
+                    ? nonPrefixedType : prefix + nonPrefixedType;
+            prefixedPropertyMasks.add(
+                    nonPrefixedPropertyMaskBuilders.get(i).setSchemaType(prefixedType).build());
+        }
+        GetResultSpecProto getResultSpec =
+                GetResultSpecProto.newBuilder().addAllTypePropertyMasks(prefixedPropertyMasks)
+                        .build();
+
+        String finalNamespace = createPrefix(packageName, databaseName) + namespace;
+        if (mLogUtil.isPiiTraceEnabled()) {
+            mLogUtil.piiTrace(
+                    "getDocument, request", finalNamespace + ", " + id + "," + getResultSpec);
+        }
+        GetResultProto getResultProto =
+                mIcingSearchEngineLocked.get(finalNamespace, id, getResultSpec);
+        mLogUtil.piiTrace("getDocument, response", getResultProto.getStatus(), getResultProto);
+        checkSuccess(getResultProto.getStatus());
+
+        return getResultProto.getDocument();
+    }
+
+    /**
      * Executes a query against the AppSearch index and returns results.
      *
      * <p>This method belongs to query group.
@@ -897,16 +1278,10 @@
      *
      * <p>This method belongs to query group.
      *
-     * @param queryExpression       Query String to search.
-     * @param searchSpec            Spec for setting filters, raw query etc.
-     * @param callerPackageName     Package name of the caller, should belong to the {@code
-     *                              callerUserHandle}.
-     * @param visibilityStore       Optional visibility store to obtain system and package
-     *                              visibility settings from
-     * @param callerUid             UID of the client making the globalQuery call.
-     * @param callerHasSystemAccess Whether the caller has been positively identified as having
-     *                              access to schemas marked system surfaceable.
-     * @param logger                logger to collect globalQuery stats
+     * @param queryExpression Query String to search.
+     * @param searchSpec      Spec for setting filters, raw query etc.
+     * @param callerAccess    Visibility access info of the calling app
+     * @param logger          logger to collect globalQuery stats
      * @return The results of performing this search. It may contain an empty list of results if
      * no documents matched the query.
      * @throws AppSearchException on IcingSearchEngine error.
@@ -915,10 +1290,7 @@
     public SearchResultPage globalQuery(
             @NonNull String queryExpression,
             @NonNull SearchSpec searchSpec,
-            @NonNull String callerPackageName,
-            @Nullable VisibilityStore visibilityStore,
-            int callerUid,
-            boolean callerHasSystemAccess,
+            @NonNull CallerAccess callerAccess,
             @Nullable AppSearchLogger logger) throws AppSearchException {
         long totalLatencyStartMillis = SystemClock.elapsedRealtime();
         SearchStats.Builder sStatsBuilder = null;
@@ -926,7 +1298,7 @@
             sStatsBuilder =
                     new SearchStats.Builder(
                             SearchStats.VISIBILITY_SCOPE_GLOBAL,
-                            callerPackageName);
+                            callerAccess.getCallingPackageName());
         }
 
         mReadWriteLock.readLock().lock();
@@ -952,10 +1324,10 @@
             }
             SearchSpecToProtoConverter searchSpecToProtoConverter =
                     new SearchSpecToProtoConverter(searchSpec, prefixFilters, mNamespaceMapLocked,
-                    mSchemaMapLocked);
+                            mSchemaMapLocked);
             // Remove those inaccessible schemas.
-            searchSpecToProtoConverter.removeInaccessibleSchemaFilter(callerPackageName,
-                    visibilityStore, callerUid, callerHasSystemAccess);
+            searchSpecToProtoConverter.removeInaccessibleSchemaFilter(
+                    callerAccess, mVisibilityStoreLocked, mVisibilityCheckerLocked);
             if (searchSpecToProtoConverter.isNothingToSearch()) {
                 // there is nothing to search over given their search filters, so we can return an
                 // empty SearchResult and skip sending request to Icing.
@@ -966,7 +1338,8 @@
                             queryExpression,
                             searchSpecToProtoConverter,
                             sStatsBuilder);
-            addNextPageToken(callerPackageName, searchResultPage.getNextPageToken());
+            addNextPageToken(
+                    callerAccess.getCallingPackageName(), searchResultPage.getNextPageToken());
             return searchResultPage;
         } finally {
             mReadWriteLock.readLock().unlock();
@@ -1266,7 +1639,14 @@
 
             // Prepare notifications
             if (schemaType != null) {
-                mObserverManager.onDocumentChange(packageName, databaseName, namespace, schemaType);
+                mObserverManager.onDocumentChange(
+                        packageName,
+                        databaseName,
+                        namespace,
+                        schemaType,
+                        documentId,
+                        mVisibilityStoreLocked,
+                        mVisibilityCheckerLocked);
             }
         } finally {
             mReadWriteLock.writeLock().unlock();
@@ -1360,9 +1740,9 @@
     /**
      * Executes removeByQuery, creating change notifications for removal.
      *
-     * @param packageName         The package name that owns the documents.
-     * @param finalSearchSpec     The final search spec that has been written through
-     *                            {@link SearchSpecToProtoConverter}.
+     * @param packageName             The package name that owns the documents.
+     * @param finalSearchSpec         The final search spec that has been written through
+     *                                {@link SearchSpecToProtoConverter}.
      * @param prefixedObservedSchemas The set of prefixed schemas that have valid registered
      *                                observers. Only changes to schemas in this set will be queued.
      */
@@ -1427,7 +1807,10 @@
                             packageName,
                             /*databaseName=*/ PrefixUtil.getDatabaseName(document.getNamespace()),
                             /*namespace=*/ PrefixUtil.removePrefix(document.getNamespace()),
-                            /*schemaType=*/ PrefixUtil.removePrefix(document.getSchema()));
+                            /*schemaType=*/ PrefixUtil.removePrefix(document.getSchema()),
+                            document.getUri(),
+                            mVisibilityStoreLocked,
+                            mVisibilityCheckerLocked);
                 }
             }
 
@@ -1771,12 +2154,13 @@
                     }
                     for (String databaseName : databaseNames) {
                         String removedPrefix = createPrefix(packageName, databaseName);
-                        mSchemaMapLocked.remove(removedPrefix);
+                        Map<String, SchemaTypeConfigProto> removedSchemas =
+                                mSchemaMapLocked.remove(removedPrefix);
+                        mVisibilityStoreLocked.removeVisibility(removedSchemas.keySet());
                         mNamespaceMapLocked.remove(removedPrefix);
                     }
                 }
             }
-            //TODO(b/145759910) clear visibility setting for package.
         } finally {
             mReadWriteLock.writeLock().unlock();
         }
@@ -1951,7 +2335,7 @@
         synchronized (mNextPageTokensLocked) {
             Set<Long> nextPageTokens = mNextPageTokensLocked.get(packageName);
             if (nextPageTokens == null || !nextPageTokens.contains(nextPageToken)) {
-                throw new AppSearchException(AppSearchResult.RESULT_SECURITY_ERROR,
+                throw new AppSearchException(RESULT_SECURITY_ERROR,
                         "Package \"" + packageName + "\" cannot use nextPageToken: "
                                 + nextPageToken);
             }
@@ -1959,48 +2343,60 @@
     }
 
     /**
-     * Adds an {@link AppSearchObserverCallback} to monitor changes within the
-     * databases owned by {@code observedPackage} if they match the given
+     * Adds an {@link ObserverCallback} to monitor changes within the databases owned by
+     * {@code targetPackageName} if they match the given
      * {@link androidx.appsearch.observer.ObserverSpec}.
      *
-     * <p>If the data owned by {@code observedPackage} is not visible to you, the registration call
-     * will succeed but no notifications will be dispatched. Notifications could start flowing later
-     * if {@code observedPackage} changes its schema visibility settings.
+     * <p>If the data owned by {@code targetPackageName} is not visible to you, the registration
+     * call will succeed but no notifications will be dispatched. Notifications could start flowing
+     * later if {@code targetPackageName} changes its schema visibility settings.
      *
-     * <p>If no package matching {@code observedPackage} exists on the system, the registration call
-     * will succeed but no notifications will be dispatched. Notifications could start flowing later
-     * if {@code observedPackage} is installed and starts indexing data.
+     * <p>If no package matching {@code targetPackageName} exists on the system, the registration
+     * call will succeed but no notifications will be dispatched. Notifications could start flowing
+     * later if {@code targetPackageName} is installed and starts indexing data.
      *
      * <p>Note that this method does not take the standard read/write lock that guards I/O, so it
      * will not queue behind I/O. Therefore it is safe to call from any thread including UI or
      * binder threads.
+     *
+     * @param listeningPackageAccess Visibility information about the app that wants to receive
+     *                               notifications.
+     * @param targetPackageName      The package that owns the data the observer wants to be
+     *                               notified for.
+     * @param spec                   Describes the kind of data changes the observer should trigger
+     *                               for.
+     * @param executor               The executor on which to trigger the observer callback to
+     *                               deliver notifications.
+     * @param observer               The callback to trigger on notifications.
      */
-    public void addObserver(
-            @NonNull String observedPackage,
+    public void registerObserverCallback(
+            @NonNull CallerAccess listeningPackageAccess,
+            @NonNull String targetPackageName,
             @NonNull ObserverSpec spec,
             @NonNull Executor executor,
-            @NonNull AppSearchObserverCallback observer) {
+            @NonNull ObserverCallback observer) {
         // This method doesn't consult mSchemaMap or mNamespaceMap, and it will register
         // observers for types that don't exist. This is intentional because we notify for types
         // being created or removed. If we only registered observer for existing types, it would
         // be impossible to ever dispatch a notification of a type being added.
-        mObserverManager.addObserver(observedPackage, spec, executor, observer);
+        mObserverManager.registerObserverCallback(
+                listeningPackageAccess, targetPackageName, spec, executor, observer);
     }
 
     /**
-     * Removes an {@link AppSearchObserverCallback} from watching the databases owned by
-     * {@code observedPackage}.
+     * Removes an {@link ObserverCallback} from watching the databases owned by
+     * {@code targetPackageName}.
      *
      * <p>All observers which compare equal to the given observer via
-     * {@link AppSearchObserverCallback#equals} are removed. This may be 0, 1, or many observers.
+     * {@link ObserverCallback#equals} are removed. This may be 0, 1, or many observers.
      *
      * <p>Note that this method does not take the standard read/write lock that guards I/O, so it
      * will not queue behind I/O. Therefore it is safe to call from any thread including UI or
      * binder threads.
      */
-    public void removeObserver(
-            @NonNull String observedPackage, @NonNull AppSearchObserverCallback observer) {
-        mObserverManager.removeObserver(observedPackage, observer);
+    public void unregisterObserverCallback(
+            @NonNull String targetPackageName, @NonNull ObserverCallback observer) {
+        mObserverManager.unregisterObserverCallback(targetPackageName, observer);
     }
 
     /**
@@ -2166,6 +2562,25 @@
     }
 
     /**
+     * Returns all prefixed schema types saved in AppSearch.
+     *
+     * <p>This method is inefficient to call repeatedly.
+     */
+    @NonNull
+    public List<String> getAllPrefixedSchemaTypes() {
+        mReadWriteLock.readLock().lock();
+        try {
+            List<String> cachedPrefixedSchemaTypes = new ArrayList<>();
+            for (Map<String, SchemaTypeConfigProto> value : mSchemaMapLocked.values()) {
+                cachedPrefixedSchemaTypes.addAll(value.keySet());
+            }
+            return cachedPrefixedSchemaTypes;
+        } finally {
+            mReadWriteLock.readLock().unlock();
+        }
+    }
+
+    /**
      * Converts an erroneous status code from the Icing status enums to the AppSearchResult enums.
      *
      * <p>Callers should ensure that the status code is not OK or WARNING_DATA_LOSS.
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchMigrationHelper.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchMigrationHelper.java
index 393f8f2..312c2ed 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchMigrationHelper.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchMigrationHelper.java
@@ -165,7 +165,7 @@
      *                        {@link androidx.appsearch.app.SetSchemaResponse.MigrationFailure}
      *                        added in.
      * @return  the {@link SetSchemaResponse} for this
-     *          {@link androidx.appsearch.app.AppSearchSession#setSchema} call.
+     *          {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync} call.
      *
      * @throws IOException        on i/o problem
      * @throws AppSearchException on AppSearch problem
@@ -185,7 +185,12 @@
             while (!codedInputStream.isAtEnd()) {
                 GenericDocument document = readDocumentFromInputStream(codedInputStream);
                 try {
-                    mAppSearchImpl.putDocument(mPackageName, mDatabaseName, document,
+                    // During schema migrations, only schema change notifications are dispatched.
+                    mAppSearchImpl.putDocument(
+                            mPackageName,
+                            mDatabaseName,
+                            document,
+                            /*sendChangeNotifications=*/ false,
                             /*logger=*/ null);
                     savedDocsCount++;
                 } catch (Throwable t) {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/GlobalSearchSessionImpl.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/GlobalSearchSessionImpl.java
index 6c9e456..ef8ec3b 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/GlobalSearchSessionImpl.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/GlobalSearchSessionImpl.java
@@ -16,24 +16,34 @@
 // @exportToFramework:skipFile()
 package androidx.appsearch.localstorage;
 
+import static androidx.appsearch.app.AppSearchResult.throwableToFailedResult;
+
+import android.annotation.SuppressLint;
 import android.content.Context;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.appsearch.app.AppSearchBatchResult;
 import androidx.appsearch.app.AppSearchResult;
 import androidx.appsearch.app.Features;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.GetByDocumentIdRequest;
+import androidx.appsearch.app.GetSchemaResponse;
 import androidx.appsearch.app.GlobalSearchSession;
 import androidx.appsearch.app.ReportSystemUsageRequest;
 import androidx.appsearch.app.SearchResults;
 import androidx.appsearch.app.SearchSpec;
 import androidx.appsearch.exceptions.AppSearchException;
 import androidx.appsearch.localstorage.util.FutureUtil;
-import androidx.appsearch.observer.AppSearchObserverCallback;
+import androidx.appsearch.localstorage.visibilitystore.CallerAccess;
+import androidx.appsearch.observer.ObserverCallback;
 import androidx.appsearch.observer.ObserverSpec;
 import androidx.core.util.Preconditions;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
+import java.util.List;
+import java.util.Map;
 import java.util.concurrent.Executor;
 
 /**
@@ -48,12 +58,12 @@
     private final Executor mExecutor;
     private final Features mFeatures;
     private final Context mContext;
+    @Nullable private final AppSearchLogger mLogger;
+
+    private final CallerAccess mSelfCallerAccess;
 
     private boolean mIsClosed = false;
 
-    @Nullable
-    private final AppSearchLogger mLogger;
-
     GlobalSearchSessionImpl(
             @NonNull AppSearchImpl appSearchImpl,
             @NonNull Executor executor,
@@ -65,6 +75,37 @@
         mFeatures = Preconditions.checkNotNull(features);
         mContext = Preconditions.checkNotNull(context);
         mLogger = logger;
+
+        mSelfCallerAccess = new CallerAccess(/*callingPackageName=*/mContext.getPackageName());
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentIdAsync(
+            @NonNull String packageName,
+            @NonNull String databaseName,
+            @NonNull GetByDocumentIdRequest request) {
+        Preconditions.checkNotNull(packageName);
+        Preconditions.checkNotNull(databaseName);
+        Preconditions.checkNotNull(request);
+        Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
+        return FutureUtil.execute(mExecutor, () -> {
+            AppSearchBatchResult.Builder<String, GenericDocument> resultBuilder =
+                    new AppSearchBatchResult.Builder<>();
+
+            Map<String, List<String>> typePropertyPaths = request.getProjectionsInternal();
+            CallerAccess access = new CallerAccess(mContext.getPackageName());
+            for (String id : request.getIds()) {
+                try {
+                    GenericDocument document = mAppSearchImpl.globalGetDocument(packageName,
+                            databaseName, request.getNamespace(), id, typePropertyPaths, access);
+                    resultBuilder.setSuccess(id, document);
+                } catch (Throwable t) {
+                    resultBuilder.setResult(id, throwableToFailedResult(t));
+                }
+            }
+            return resultBuilder.build();
+        });
     }
 
     @NonNull
@@ -92,7 +133,8 @@
      */
     @NonNull
     @Override
-    public ListenableFuture<Void> reportSystemUsage(@NonNull ReportSystemUsageRequest request) {
+    public ListenableFuture<Void> reportSystemUsageAsync(
+            @NonNull ReportSystemUsageRequest request) {
         Preconditions.checkNotNull(request);
         Preconditions.checkState(!mIsClosed, "GlobalSearchSession has already been closed");
         return FutureUtil.execute(mExecutor, () -> {
@@ -102,6 +144,18 @@
         });
     }
 
+    @SuppressLint("KotlinPropertyAccess")
+    @NonNull
+    @Override
+    public ListenableFuture<GetSchemaResponse> getSchemaAsync(
+            @NonNull String packageName, @NonNull String databaseName) {
+        Preconditions.checkNotNull(packageName);
+        Preconditions.checkNotNull(databaseName);
+        Preconditions.checkState(!mIsClosed, "GlobalSearchSession has already been closed");
+        return FutureUtil.execute(mExecutor,
+                () -> mAppSearchImpl.getSchema(packageName, databaseName, mSelfCallerAccess));
+    }
+
     @NonNull
     @Override
     public Features getFeatures() {
@@ -109,36 +163,41 @@
     }
 
     @Override
-    public void addObserver(
-            @NonNull String observedPackage,
+    public void registerObserverCallback(
+            @NonNull String targetPackageName,
             @NonNull ObserverSpec spec,
             @NonNull Executor executor,
-            @NonNull AppSearchObserverCallback observer) {
-        Preconditions.checkNotNull(observedPackage);
+            @NonNull ObserverCallback observer) {
+        Preconditions.checkNotNull(targetPackageName);
         Preconditions.checkNotNull(spec);
         Preconditions.checkNotNull(executor);
         Preconditions.checkNotNull(observer);
         // LocalStorage does not support observing data from other packages.
-        if (!observedPackage.equals(mContext.getPackageName())) {
+        if (!targetPackageName.equals(mContext.getPackageName())) {
             throw new UnsupportedOperationException(
                     "Local storage implementation does not support receiving change notifications "
                             + "from other packages.");
         }
-        mAppSearchImpl.addObserver(observedPackage, spec, executor, observer);
+        mAppSearchImpl.registerObserverCallback(
+                /*listeningPackageAccess=*/mSelfCallerAccess,
+                /*targetPackageName=*/targetPackageName,
+                spec,
+                executor,
+                observer);
     }
 
     @Override
-    public void removeObserver(
-            @NonNull String observedPackage, @NonNull AppSearchObserverCallback observer) {
-        Preconditions.checkNotNull(observedPackage);
+    public void unregisterObserverCallback(
+            @NonNull String targetPackageName, @NonNull ObserverCallback observer) {
+        Preconditions.checkNotNull(targetPackageName);
         Preconditions.checkNotNull(observer);
         // LocalStorage does not support observing data from other packages.
-        if (!observedPackage.equals(mContext.getPackageName())) {
+        if (!targetPackageName.equals(mContext.getPackageName())) {
             throw new UnsupportedOperationException(
                     "Local storage implementation does not support receiving change notifications "
                             + "from other packages.");
         }
-        mAppSearchImpl.removeObserver(observedPackage, observer);
+        mAppSearchImpl.unregisterObserverCallback(targetPackageName, observer);
     }
 
     @Override
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/LocalStorage.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/LocalStorage.java
index 3ffb93d..6935b5e 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/LocalStorage.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/LocalStorage.java
@@ -270,7 +270,7 @@
      *                {@link AppSearchSession}
      */
     @NonNull
-    public static ListenableFuture<AppSearchSession> createSearchSession(
+    public static ListenableFuture<AppSearchSession> createSearchSessionAsync(
             @NonNull SearchContext context) {
         Preconditions.checkNotNull(context);
         return FutureUtil.execute(context.mExecutor, () -> {
@@ -281,6 +281,18 @@
     }
 
     /**
+     * @deprecated use {@link #createSearchSessionAsync}
+     * @param context The {@link SearchContext} contains all information to create a new
+     *                {@link AppSearchSession}
+     */
+    @NonNull
+    @Deprecated
+    public static ListenableFuture<AppSearchSession> createSearchSession(
+            @NonNull SearchContext context) {
+        return createSearchSessionAsync(context);
+    }
+
+    /**
      * Opens a new {@link GlobalSearchSession} on this storage.
      *
      * <p>This process requires a native search library. If it's not created, the initialization
@@ -290,7 +302,7 @@
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
-    public static ListenableFuture<GlobalSearchSession> createGlobalSearchSession(
+    public static ListenableFuture<GlobalSearchSession> createGlobalSearchSessionAsync(
             @NonNull GlobalSearchContext context) {
         Preconditions.checkNotNull(context);
         return FutureUtil.execute(context.mExecutor, () -> {
@@ -301,6 +313,18 @@
     }
 
     /**
+     * @deprecated use {@link #createGlobalSearchSessionAsync}
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @NonNull
+    @Deprecated
+    public static ListenableFuture<GlobalSearchSession> createGlobalSearchSession(
+            @NonNull GlobalSearchContext context) {
+        return createGlobalSearchSessionAsync(context);
+    }
+
+    /**
      * Returns the singleton instance of {@link LocalStorage}.
      *
      * <p>If the system is not initialized, it will be initialized using the provided
@@ -342,7 +366,8 @@
                 icingDir,
                 new UnlimitedLimitConfig(),
                 initStatsBuilder,
-                new JetpackOptimizeStrategy());
+                new JetpackOptimizeStrategy(),
+                /*visibilityChecker=*/null);
 
         if (logger != null) {
             initStatsBuilder.setTotalLatencyMillis(
@@ -382,7 +407,7 @@
                 mAppSearchImpl,
                 context.mExecutor,
                 new AlwaysSupportedFeatures(),
-                context.mContext.getPackageName(),
+                context.mContext,
                 context.mDatabaseName,
                 context.mLogger);
     }
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/ObserverManager.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/ObserverManager.java
index 0d49147..c25be25 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/ObserverManager.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/ObserverManager.java
@@ -22,22 +22,29 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
-import androidx.appsearch.observer.AppSearchObserverCallback;
+import androidx.appsearch.localstorage.util.PrefixUtil;
+import androidx.appsearch.localstorage.visibilitystore.CallerAccess;
+import androidx.appsearch.localstorage.visibilitystore.VisibilityChecker;
+import androidx.appsearch.localstorage.visibilitystore.VisibilityStore;
+import androidx.appsearch.localstorage.visibilitystore.VisibilityUtil;
 import androidx.appsearch.observer.DocumentChangeInfo;
+import androidx.appsearch.observer.ObserverCallback;
 import androidx.appsearch.observer.ObserverSpec;
+import androidx.appsearch.observer.SchemaChangeInfo;
 import androidx.collection.ArrayMap;
 import androidx.collection.ArraySet;
 import androidx.core.util.ObjectsCompat;
 import androidx.core.util.Preconditions;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Executor;
 
 /**
- * Manages {@link AppSearchObserverCallback} instances and queues notifications to them for later
+ * Manages {@link ObserverCallback} instances and queues notifications to them for later
  * dispatch.
  *
  * <p>This class is thread-safe.
@@ -84,72 +91,94 @@
     }
 
     private static final class ObserverInfo {
+        /** The package which registered the observer. */
+        final CallerAccess mListeningPackageAccess;
         final ObserverSpec mObserverSpec;
         final Executor mExecutor;
-        final AppSearchObserverCallback mObserver;
-        volatile Set<DocumentChangeGroupKey> mDocumentChanges = new ArraySet<>();
+        final ObserverCallback mObserverCallback;
+        // Values is a set of document IDs
+        volatile Map<DocumentChangeGroupKey, Set<String>> mDocumentChanges = new ArrayMap<>();
+        // Keys are database prefixes, values are a set of schema names
+        volatile Map<String, Set<String>> mSchemaChanges = new ArrayMap<>();
 
         ObserverInfo(
+                @NonNull CallerAccess listeningPackageAccess,
                 @NonNull ObserverSpec observerSpec,
                 @NonNull Executor executor,
-                @NonNull AppSearchObserverCallback observer) {
+                @NonNull ObserverCallback observerCallback) {
+            mListeningPackageAccess = Preconditions.checkNotNull(listeningPackageAccess);
             mObserverSpec = Preconditions.checkNotNull(observerSpec);
             mExecutor = Preconditions.checkNotNull(executor);
-            mObserver = Preconditions.checkNotNull(observer);
+            mObserverCallback = Preconditions.checkNotNull(observerCallback);
         }
     }
 
     private final Object mLock = new Object();
 
-    /** Maps observed package to observer infos watching something in that package. */
+    /** Maps target packages to ObserverInfos watching something in that package. */
     @GuardedBy("mLock")
     private final Map<String, List<ObserverInfo>> mObserversLocked = new ArrayMap<>();
 
     private volatile boolean mHasNotifications = false;
 
     /**
-     * Adds an {@link AppSearchObserverCallback} to monitor changes within the
-     * databases owned by {@code observedPackage} if they match the given
+     * Adds an {@link ObserverCallback} to monitor changes within the databases owned by
+     * {@code targetPackageName} if they match the given
      * {@link androidx.appsearch.observer.ObserverSpec}.
      *
-     * <p>If the data owned by {@code observedPackage} is not visible to you, the registration call
-     * will succeed but no notifications will be dispatched. Notifications could start flowing later
-     * if {@code observedPackage} changes its schema visibility settings.
+     * <p>If the data owned by {@code targetPackageName} is not visible to you, the registration
+     * call will succeed but no notifications will be dispatched. Notifications could start flowing
+     * later if {@code targetPackageName} changes its schema visibility settings.
      *
-     * <p>If no package matching {@code observedPackage} exists on the system, the registration call
-     * will succeed but no notifications will be dispatched. Notifications could start flowing later
-     * if {@code observedPackage} is installed and starts indexing data.
+     * <p>If no package matching {@code targetPackageName} exists on the system, the registration
+     * call will succeed but no notifications will be dispatched. Notifications could start flowing
+     * later if {@code targetPackageName} is installed and starts indexing data.
+     *
+     * <p>Note that this method does not take the standard read/write lock that guards I/O, so it
+     * will not queue behind I/O. Therefore it is safe to call from any thread including UI or
+     * binder threads.
+     *
+     * @param listeningPackageAccess Visibility information about the app that wants to receive
+     *                               notifications.
+     * @param targetPackageName      The package that owns the data the observerCallback wants to be
+     *                               notified for.
+     * @param spec                   Describes the kind of data changes the observerCallback should
+     *                               trigger for.
+     * @param executor               The executor on which to trigger the observerCallback callback
+     *                               to deliver notifications.
+     * @param observerCallback       The callback to trigger on notifications.
      */
-    public void addObserver(
-            @NonNull String observedPackage,
+    public void registerObserverCallback(
+            @NonNull CallerAccess listeningPackageAccess,
+            @NonNull String targetPackageName,
             @NonNull ObserverSpec spec,
             @NonNull Executor executor,
-            @NonNull AppSearchObserverCallback observer) {
+            @NonNull ObserverCallback observerCallback) {
         synchronized (mLock) {
-            List<ObserverInfo> infos = mObserversLocked.get(observedPackage);
+            List<ObserverInfo> infos = mObserversLocked.get(targetPackageName);
             if (infos == null) {
                 infos = new ArrayList<>();
-                mObserversLocked.put(observedPackage, infos);
+                mObserversLocked.put(targetPackageName, infos);
             }
-            infos.add(new ObserverInfo(spec, executor, observer));
+            infos.add(new ObserverInfo(listeningPackageAccess, spec, executor, observerCallback));
         }
     }
 
     /**
-     * Removes all observers that match via {@link AppSearchObserverCallback#equals} to the given
-     * observer from watching the observedPackage.
+     * Removes all observers that match via {@link ObserverCallback#equals} to the given observer
+     * from watching the targetPackageName.
      *
      * <p>Pending notifications queued for this observer, if any, are discarded.
      */
-    public void removeObserver(
-            @NonNull String observedPackage, @NonNull AppSearchObserverCallback observer) {
+    public void unregisterObserverCallback(
+            @NonNull String targetPackageName, @NonNull ObserverCallback observer) {
         synchronized (mLock) {
-            List<ObserverInfo> infos = mObserversLocked.get(observedPackage);
+            List<ObserverInfo> infos = mObserversLocked.get(targetPackageName);
             if (infos == null) {
                 return;
             }
             for (int i = 0; i < infos.size(); i++) {
-                if (infos.get(i).mObserver.equals(observer)) {
+                if (infos.get(i).mObserverCallback.equals(observer)) {
                     infos.remove(i);
                     i--;
                 }
@@ -162,28 +191,105 @@
      *
      * <p>The notification will be queued in memory for later dispatch. You must call
      * {@link #dispatchAndClearPendingNotifications} to dispatch all such pending notifications.
+     *
+     * @param visibilityStore   Store for visibility information. If not provided, only access to
+     *                          own data will be allowed.
+     * @param visibilityChecker Checker for visibility access. If not provided, only access to own
+     *                          data will be allowed.
      */
     public void onDocumentChange(
             @NonNull String packageName,
             @NonNull String databaseName,
             @NonNull String namespace,
-            @NonNull String schemaType) {
+            @NonNull String schemaType,
+            @NonNull String documentId,
+            @Nullable VisibilityStore visibilityStore,
+            @Nullable VisibilityChecker visibilityChecker) {
         synchronized (mLock) {
             List<ObserverInfo> allObserverInfosForPackage = mObserversLocked.get(packageName);
             if (allObserverInfosForPackage == null || allObserverInfosForPackage.isEmpty()) {
                 return; // No observers for this type
             }
             // Enqueue changes for later dispatch once the call returns
+            String prefixedSchema =
+                    PrefixUtil.createPrefix(packageName, databaseName) + schemaType;
             DocumentChangeGroupKey key = null;
             for (int i = 0; i < allObserverInfosForPackage.size(); i++) {
                 ObserverInfo observerInfo = allObserverInfosForPackage.get(i);
-                if (matchesSpec(schemaType, observerInfo.mObserverSpec)) {
-                    if (key == null) {
-                        key = new DocumentChangeGroupKey(
-                                packageName, databaseName, namespace, schemaType);
-                    }
-                    observerInfo.mDocumentChanges.add(key);
+                if (!matchesSpec(schemaType, observerInfo.mObserverSpec)) {
+                    continue;  // Observer doesn't want this notification
                 }
+                if (!VisibilityUtil.isSchemaSearchableByCaller(
+                        /*callerAccess=*/observerInfo.mListeningPackageAccess,
+                        /*targetPackageName=*/packageName,
+                        /*prefixedSchema=*/prefixedSchema,
+                        visibilityStore,
+                        visibilityChecker)) {
+                    continue;  // Observer can't have this notification.
+                }
+                if (key == null) {
+                    key = new DocumentChangeGroupKey(
+                            packageName, databaseName, namespace, schemaType);
+                }
+                Set<String> changedDocumentIds = observerInfo.mDocumentChanges.get(key);
+                if (changedDocumentIds == null) {
+                    changedDocumentIds = new ArraySet<>();
+                    observerInfo.mDocumentChanges.put(key, changedDocumentIds);
+                }
+                changedDocumentIds.add(documentId);
+            }
+            mHasNotifications = true;
+        }
+    }
+
+    /**
+     * Enqueues a change to a schema type for a single observer.
+     *
+     * <p>The notification will be queued in memory for later dispatch. You must call
+     * {@link #dispatchAndClearPendingNotifications} to dispatch all such pending notifications.
+     *
+     * <p>Note that unlike {@link #onDocumentChange}, the changes reported here are not dropped
+     * for observers that don't have visibility. This is because the observer might have had
+     * visibility before the schema change, and a final deletion needs to be sent to it. Caller
+     * is responsible for checking visibility of these notifications.
+     *
+     * @param listeningPackageName Name of package that subscribed to notifications and has been
+     *                             validated by the caller to have the right access to receive
+     *                             this notification.
+     * @param targetPackageName Name of package that owns the changed schema types.
+     * @param databaseName Database in which the changed schema types reside.
+     * @param schemaName Unprefixed name of the changed schema type.
+     */
+    public void onSchemaChange(
+            @NonNull String listeningPackageName,
+            @NonNull String targetPackageName,
+            @NonNull String databaseName,
+            @NonNull String schemaName) {
+        synchronized (mLock) {
+            List<ObserverInfo> allObserverInfosForPackage = mObserversLocked.get(targetPackageName);
+            if (allObserverInfosForPackage == null || allObserverInfosForPackage.isEmpty()) {
+                return; // No observers for this type
+            }
+            // Enqueue changes for later dispatch once the call returns
+            String prefix = null;
+            for (int i = 0; i < allObserverInfosForPackage.size(); i++) {
+                ObserverInfo observerInfo = allObserverInfosForPackage.get(i);
+                if (!observerInfo.mListeningPackageAccess.getCallingPackageName()
+                        .equals(listeningPackageName)) {
+                    continue;  // Not the observer we've been requested to update right now.
+                }
+                if (!matchesSpec(schemaName, observerInfo.mObserverSpec)) {
+                    continue;  // Observer doesn't want this notification
+                }
+                if (prefix == null) {
+                    prefix = PrefixUtil.createPrefix(targetPackageName, databaseName);
+                }
+                Set<String> changedSchemaNames = observerInfo.mSchemaChanges.get(prefix);
+                if (changedSchemaNames == null) {
+                    changedSchemaNames = new ArraySet<>();
+                    observerInfo.mSchemaChanges.put(prefix, changedSchemaNames);
+                }
+                changedSchemaNames.add(schemaName);
             }
             mHasNotifications = true;
         }
@@ -216,6 +322,44 @@
         }
     }
 
+    /**
+     * Returns package names of listening packages registered for changes on the given
+     * {@code packageName}, {@code databaseName} and unprefixed {@code schemaType}, only if they
+     * have access to that type according to the provided {@code visibilityChecker}.
+     */
+    @NonNull
+    public Set<String> getObserversForSchemaType(
+            @NonNull String packageName,
+            @NonNull String databaseName,
+            @NonNull String schemaType,
+            @Nullable VisibilityStore visibilityStore,
+            @Nullable VisibilityChecker visibilityChecker) {
+        synchronized (mLock) {
+            List<ObserverInfo> allObserverInfosForPackage = mObserversLocked.get(packageName);
+            if (allObserverInfosForPackage == null) {
+                return Collections.emptySet();
+            }
+            Set<String> result = new ArraySet<>();
+            String prefixedSchema = PrefixUtil.createPrefix(packageName, databaseName) + schemaType;
+            for (int i = 0; i < allObserverInfosForPackage.size(); i++) {
+                ObserverInfo observerInfo = allObserverInfosForPackage.get(i);
+                if (!matchesSpec(schemaType, observerInfo.mObserverSpec)) {
+                    continue;  // Observer doesn't want this notification
+                }
+                if (!VisibilityUtil.isSchemaSearchableByCaller(
+                        /*callerAccess=*/observerInfo.mListeningPackageAccess,
+                        /*targetPackageName=*/packageName,
+                        /*prefixedSchema=*/prefixedSchema,
+                        visibilityStore,
+                        visibilityChecker)) {
+                    continue;  // Observer can't have this notification.
+                }
+                result.add(observerInfo.mListeningPackageAccess.getCallingPackageName());
+            }
+            return result;
+        }
+    }
+
     /** Returns whether any notifications have been queued for dispatch. */
     public boolean hasNotifications() {
         return mHasNotifications;
@@ -243,28 +387,52 @@
     @GuardedBy("mLock")
     private void dispatchAndClearPendingNotificationsLocked(@NonNull ObserverInfo observerInfo) {
         // Get and clear the pending changes
-        Set<DocumentChangeGroupKey> documentChanges = observerInfo.mDocumentChanges;
-        if (documentChanges.isEmpty()) {
+        Map<String, Set<String>> schemaChanges = observerInfo.mSchemaChanges;
+        Map<DocumentChangeGroupKey, Set<String>> documentChanges = observerInfo.mDocumentChanges;
+        if (schemaChanges.isEmpty() && documentChanges.isEmpty()) {
             return;
         }
-        observerInfo.mDocumentChanges = new ArraySet<>();
+        if (!schemaChanges.isEmpty()) {
+            observerInfo.mSchemaChanges = new ArrayMap<>();
+        }
+        if (!documentChanges.isEmpty()) {
+            observerInfo.mDocumentChanges = new ArrayMap<>();
+        }
 
         // Dispatch the pending changes
         observerInfo.mExecutor.execute(() -> {
-            for (DocumentChangeGroupKey entry : documentChanges) {
-                // TODO(b/193494000): Buffer document URIs as the values of mDocumentChanges
-                // and include them in the final ChangeInfo
-                DocumentChangeInfo documentChangeInfo = new DocumentChangeInfo(
-                        entry.mPackageName,
-                        entry.mDatabaseName,
-                        entry.mNamespace,
-                        entry.mSchemaName);
+            // Schema changes
+            if (!schemaChanges.isEmpty()) {
+                for (Map.Entry<String, Set<String>> entry : schemaChanges.entrySet()) {
+                    SchemaChangeInfo schemaChangeInfo = new SchemaChangeInfo(
+                            /*packageName=*/PrefixUtil.getPackageName(entry.getKey()),
+                            /*databaseName=*/PrefixUtil.getDatabaseName(entry.getKey()),
+                            /*changedSchemaNames=*/entry.getValue());
 
-                try {
-                    // TODO(b/193494000): Add code to dispatch SchemaChangeInfo too.
-                    observerInfo.mObserver.onDocumentChanged(documentChangeInfo);
-                } catch (Throwable t) {
-                    Log.w(TAG, "AppSearchObserverCallback threw exception during dispatch", t);
+                    try {
+                        observerInfo.mObserverCallback.onSchemaChanged(schemaChangeInfo);
+                    } catch (Throwable t) {
+                        Log.w(TAG, "ObserverCallback threw exception during dispatch", t);
+                    }
+                }
+            }
+
+            // Document changes
+            if (!documentChanges.isEmpty()) {
+                for (Map.Entry<DocumentChangeGroupKey, Set<String>> entry
+                        : documentChanges.entrySet()) {
+                    DocumentChangeInfo documentChangeInfo = new DocumentChangeInfo(
+                            entry.getKey().mPackageName,
+                            entry.getKey().mDatabaseName,
+                            entry.getKey().mNamespace,
+                            entry.getKey().mSchemaName,
+                            entry.getValue());
+
+                    try {
+                        observerInfo.mObserverCallback.onDocumentChanged(documentChangeInfo);
+                    } catch (Throwable t) {
+                        Log.w(TAG, "ObserverCallback threw exception during dispatch", t);
+                    }
                 }
             }
         });
@@ -280,12 +448,6 @@
     private static boolean matchesSpec(
             @NonNull String schemaType, @NonNull ObserverSpec observerSpec) {
         Set<String> schemaFilters = observerSpec.getFilterSchemas();
-        if (!schemaFilters.isEmpty() && !schemaFilters.contains(schemaType)) {
-            return false;
-        }
-        // TODO(b/193494000): We also need to check VisibilityStore to see if the observer is
-        //  allowed to access this type before granting access. Note if fixing this TODO makes the
-        //  method non-static we need to handle locking.
-        return true;
+        return schemaFilters.isEmpty() || schemaFilters.contains(schemaType);
     }
 }
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/SearchResultsImpl.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/SearchResultsImpl.java
index 761ebfd..8da40bbc 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/SearchResultsImpl.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/SearchResultsImpl.java
@@ -16,18 +16,15 @@
 // @exportToFramework:skipFile()
 package androidx.appsearch.localstorage;
 
-import android.os.Process;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.appsearch.app.AppSearchResult;
 import androidx.appsearch.app.SearchResult;
 import androidx.appsearch.app.SearchResultPage;
 import androidx.appsearch.app.SearchResults;
 import androidx.appsearch.app.SearchSpec;
-import androidx.appsearch.exceptions.AppSearchException;
 import androidx.appsearch.localstorage.stats.SearchStats;
 import androidx.appsearch.localstorage.util.FutureUtil;
+import androidx.appsearch.localstorage.visibilitystore.CallerAccess;
 import androidx.core.util.Preconditions;
 
 import com.google.common.util.concurrent.ListenableFuture;
@@ -40,11 +37,13 @@
 
     private final Executor mExecutor;
 
-    // The package name to search over. If null, this will search over all package names.
-    @Nullable
+    /* The package name of the current app which is using the local backend. */
     private final String mPackageName;
 
-    // The database name to search over. If null, this will search over all database names.
+    /** A CallerAccess object describing local-only access of the current app. */
+    private final CallerAccess mSelfCallerAccess;
+
+    /* The database name to search over. If null, this will search over all database names. */
     @Nullable
     private final String mDatabaseName;
 
@@ -69,14 +68,15 @@
     SearchResultsImpl(
             @NonNull AppSearchImpl appSearchImpl,
             @NonNull Executor executor,
-            @Nullable String packageName,
+            @NonNull String packageName,
             @Nullable String databaseName,
             @NonNull String queryExpression,
             @NonNull SearchSpec searchSpec,
             @Nullable AppSearchLogger logger) {
         mAppSearchImpl = Preconditions.checkNotNull(appSearchImpl);
         mExecutor = Preconditions.checkNotNull(executor);
-        mPackageName = packageName;
+        mPackageName = Preconditions.checkNotNull(packageName);
+        mSelfCallerAccess = new CallerAccess(/*callingPackageName=*/mPackageName);
         mDatabaseName = databaseName;
         mQueryExpression = Preconditions.checkNotNull(queryExpression);
         mSearchSpec = Preconditions.checkNotNull(searchSpec);
@@ -85,27 +85,17 @@
 
     @Override
     @NonNull
-    public ListenableFuture<List<SearchResult>> getNextPage() {
+    public ListenableFuture<List<SearchResult>> getNextPageAsync() {
         Preconditions.checkState(!mIsClosed, "SearchResults has already been closed");
         return FutureUtil.execute(mExecutor, () -> {
             SearchResultPage searchResultPage;
             if (mIsFirstLoad) {
                 mIsFirstLoad = false;
-                if (mPackageName == null) {
-                    throw new AppSearchException(
-                            AppSearchResult.RESULT_INVALID_ARGUMENT,
-                            "Invalid null package name for query");
-                } else if (mDatabaseName == null) {
+                if (mDatabaseName == null) {
                     mVisibilityScope = SearchStats.VISIBILITY_SCOPE_GLOBAL;
                     // Global queries aren't restricted to a single database
                     searchResultPage = mAppSearchImpl.globalQuery(
-                            mQueryExpression,
-                            mSearchSpec,
-                            mPackageName,
-                            /*visibilityStore=*/ null,
-                            Process.myUid(),
-                            /*callerHasSystemAccess=*/ false,
-                            mLogger);
+                            mQueryExpression, mSearchSpec, mSelfCallerAccess, mLogger);
                 } else {
                     mVisibilityScope = SearchStats.VISIBILITY_SCOPE_LOCAL;
                     // Normal local query, pass in specified database.
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/SearchSessionImpl.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/SearchSessionImpl.java
index a695642..5f88880 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/SearchSessionImpl.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/SearchSessionImpl.java
@@ -18,6 +18,7 @@
 
 import static androidx.appsearch.app.AppSearchResult.throwableToFailedResult;
 
+import android.content.Context;
 import android.os.SystemClock;
 import android.util.Log;
 
@@ -31,7 +32,6 @@
 import androidx.appsearch.app.GetByDocumentIdRequest;
 import androidx.appsearch.app.GetSchemaResponse;
 import androidx.appsearch.app.Migrator;
-import androidx.appsearch.app.PackageIdentifier;
 import androidx.appsearch.app.PutDocumentsRequest;
 import androidx.appsearch.app.RemoveByDocumentIdRequest;
 import androidx.appsearch.app.ReportUsageRequest;
@@ -40,14 +40,15 @@
 import androidx.appsearch.app.SetSchemaRequest;
 import androidx.appsearch.app.SetSchemaResponse;
 import androidx.appsearch.app.StorageInfo;
+import androidx.appsearch.app.VisibilityDocument;
 import androidx.appsearch.exceptions.AppSearchException;
 import androidx.appsearch.localstorage.stats.OptimizeStats;
 import androidx.appsearch.localstorage.stats.RemoveStats;
 import androidx.appsearch.localstorage.stats.SchemaMigrationStats;
 import androidx.appsearch.localstorage.stats.SetSchemaStats;
 import androidx.appsearch.localstorage.util.FutureUtil;
+import androidx.appsearch.localstorage.visibilitystore.CallerAccess;
 import androidx.appsearch.util.SchemaMigrationUtil;
-import androidx.collection.ArrayMap;
 import androidx.collection.ArraySet;
 import androidx.core.util.Preconditions;
 
@@ -70,49 +71,50 @@
  */
 class SearchSessionImpl implements AppSearchSession {
     private static final String TAG = "AppSearchSessionImpl";
+
     private final AppSearchImpl mAppSearchImpl;
     private final Executor mExecutor;
     private final Features mFeatures;
-    private final String mPackageName;
+    private final Context mContext;
     private final String mDatabaseName;
+    @Nullable private final AppSearchLogger mLogger;
+
+    private final String mPackageName;
+    private final CallerAccess mSelfCallerAccess;
+
     private volatile boolean mIsMutated = false;
     private volatile boolean mIsClosed = false;
-    @Nullable private final AppSearchLogger mLogger;
 
     SearchSessionImpl(
             @NonNull AppSearchImpl appSearchImpl,
             @NonNull Executor executor,
             @NonNull Features features,
-            @NonNull String packageName,
+            @NonNull Context context,
             @NonNull String databaseName,
             @Nullable AppSearchLogger logger) {
         mAppSearchImpl = Preconditions.checkNotNull(appSearchImpl);
         mExecutor = Preconditions.checkNotNull(executor);
         mFeatures = Preconditions.checkNotNull(features);
-        mPackageName = packageName;
+        mContext = Preconditions.checkNotNull(context);
         mDatabaseName = Preconditions.checkNotNull(databaseName);
         mLogger = logger;
+
+        mPackageName = mContext.getPackageName();
+        mSelfCallerAccess = new CallerAccess(/*callingPackageName=*/mPackageName);
     }
 
     @Override
     @NonNull
-    public ListenableFuture<SetSchemaResponse> setSchema(
+    public ListenableFuture<SetSchemaResponse> setSchemaAsync(
             @NonNull SetSchemaRequest request) {
         Preconditions.checkNotNull(request);
         Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
 
         ListenableFuture<SetSchemaResponse> future = execute(() -> {
             long startMillis = SystemClock.elapsedRealtime();
-
-            // Convert the inner set into a List since Binder can't handle Set.
-            Map<String, Set<PackageIdentifier>> schemasVisibleToPackages =
-                    request.getSchemasVisibleToPackagesInternal();
-            Map<String, List<PackageIdentifier>> copySchemasVisibleToPackages = new ArrayMap<>();
-            for (Map.Entry<String, Set<PackageIdentifier>> entry :
-                    schemasVisibleToPackages.entrySet()) {
-                copySchemasVisibleToPackages.put(entry.getKey(),
-                        new ArrayList<>(entry.getValue()));
-            }
+            // Extract a Map<schema, VisibilityDocument> from the request.
+            List<VisibilityDocument> visibilityDocuments = VisibilityDocument
+                    .toVisibilityDocuments(request);
 
             SetSchemaStats.Builder setSchemaStatsBuilder = null;
             if (mLogger != null) {
@@ -123,20 +125,25 @@
             // No need to trigger migration if user never set migrator.
             if (migrators.size() == 0) {
                 SetSchemaResponse setSchemaResponse =
-                        setSchemaNoMigrations(request, copySchemasVisibleToPackages,
-                                setSchemaStatsBuilder);
+                        setSchemaNoMigrations(request, visibilityDocuments, setSchemaStatsBuilder);
+
+                // Schedule a task to dispatch change notifications. See requirements for where the
+                // method is called documented in the method description.
+                dispatchChangeNotifications();
+
                 if (setSchemaStatsBuilder != null) {
                     setSchemaStatsBuilder.setTotalLatencyMillis(
                             (int) (SystemClock.elapsedRealtime() - startMillis));
                     mLogger.logStats(setSchemaStatsBuilder.build());
                 }
+
                 return setSchemaResponse;
             }
 
             // Migration process
             // 1. Validate and retrieve all active migrators.
-            GetSchemaResponse getSchemaResponse =
-                    mAppSearchImpl.getSchema(mPackageName, mDatabaseName);
+            GetSchemaResponse getSchemaResponse = mAppSearchImpl.getSchema(
+                    mPackageName, mDatabaseName, mSelfCallerAccess);
             int currentVersion = getSchemaResponse.getVersion();
             int finalVersion = request.getVersion();
             Map<String, Migrator> activeMigrators = SchemaMigrationUtil.getActiveMigrators(
@@ -144,8 +151,7 @@
             // No need to trigger migration if no migrator is active.
             if (activeMigrators.size() == 0) {
                 SetSchemaResponse setSchemaResponse =
-                        setSchemaNoMigrations(request, copySchemasVisibleToPackages,
-                                setSchemaStatsBuilder);
+                        setSchemaNoMigrations(request, visibilityDocuments, setSchemaStatsBuilder);
                 if (setSchemaStatsBuilder != null) {
                     setSchemaStatsBuilder.setTotalLatencyMillis(
                             (int) (SystemClock.elapsedRealtime() - startMillis));
@@ -161,9 +167,7 @@
                     mPackageName,
                     mDatabaseName,
                     new ArrayList<>(request.getSchemas()),
-                    /*visibilityStore=*/ null,
-                    new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
-                    copySchemasVisibleToPackages,
+                    visibilityDocuments,
                     /*forceOverride=*/false,
                     request.getVersion(),
                     setSchemaStatsBuilder);
@@ -197,9 +201,7 @@
                             mPackageName,
                             mDatabaseName,
                             new ArrayList<>(request.getSchemas()),
-                            /*visibilityStore=*/ null,
-                            new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
-                            copySchemasVisibleToPackages,
+                            visibilityDocuments,
                             /*forceOverride=*/ true,
                             request.getVersion(),
                             setSchemaStatsBuilder);
@@ -214,6 +216,10 @@
                         migrationHelper.readAndPutDocuments(responseBuilder,
                                 schemaMigrationStatsBuilder);
 
+                // Schedule a task to dispatch change notifications. See requirements for where the
+                // method is called documented in the method description.
+                dispatchChangeNotifications();
+
                 if (schemaMigrationStatsBuilder != null) {
                     long endMillis = SystemClock.elapsedRealtime();
                     schemaMigrationStatsBuilder
@@ -251,14 +257,15 @@
 
     @Override
     @NonNull
-    public ListenableFuture<GetSchemaResponse> getSchema() {
+    public ListenableFuture<GetSchemaResponse> getSchemaAsync() {
         Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
-        return execute(() -> mAppSearchImpl.getSchema(mPackageName, mDatabaseName));
+        return execute(
+                () -> mAppSearchImpl.getSchema(mPackageName, mDatabaseName, mSelfCallerAccess));
     }
 
     @NonNull
     @Override
-    public ListenableFuture<Set<String>> getNamespaces() {
+    public ListenableFuture<Set<String>> getNamespacesAsync() {
         Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
         return execute(() -> {
             List<String> namespaces = mAppSearchImpl.getNamespaces(mPackageName, mDatabaseName);
@@ -268,7 +275,7 @@
 
     @Override
     @NonNull
-    public ListenableFuture<AppSearchBatchResult<String, Void>> put(
+    public ListenableFuture<AppSearchBatchResult<String, Void>> putAsync(
             @NonNull PutDocumentsRequest request) {
         Preconditions.checkNotNull(request);
         Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
@@ -278,7 +285,12 @@
             for (int i = 0; i < request.getGenericDocuments().size(); i++) {
                 GenericDocument document = request.getGenericDocuments().get(i);
                 try {
-                    mAppSearchImpl.putDocument(mPackageName, mDatabaseName, document, mLogger);
+                    mAppSearchImpl.putDocument(
+                            mPackageName,
+                            mDatabaseName,
+                            document,
+                            /*sendChangeNotifications=*/ true,
+                            mLogger);
                     resultBuilder.setSuccess(document.getId(), /*value=*/ null);
                 } catch (Throwable t) {
                     resultBuilder.setResult(document.getId(), throwableToFailedResult(t));
@@ -303,7 +315,7 @@
 
     @Override
     @NonNull
-    public ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentId(
+    public ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentIdAsync(
             @NonNull GetByDocumentIdRequest request) {
         Preconditions.checkNotNull(request);
         Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
@@ -346,7 +358,7 @@
 
     @Override
     @NonNull
-    public ListenableFuture<Void> reportUsage(@NonNull ReportUsageRequest request) {
+    public ListenableFuture<Void> reportUsageAsync(@NonNull ReportUsageRequest request) {
         Preconditions.checkNotNull(request);
         Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
         return execute(() -> {
@@ -364,7 +376,7 @@
 
     @Override
     @NonNull
-    public ListenableFuture<AppSearchBatchResult<String, Void>> remove(
+    public ListenableFuture<AppSearchBatchResult<String, Void>> removeAsync(
             @NonNull RemoveByDocumentIdRequest request) {
         Preconditions.checkNotNull(request);
         Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
@@ -403,7 +415,7 @@
 
     @Override
     @NonNull
-    public ListenableFuture<Void> remove(
+    public ListenableFuture<Void> removeAsync(
             @NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
         Preconditions.checkNotNull(queryExpression);
         Preconditions.checkNotNull(searchSpec);
@@ -432,14 +444,14 @@
 
     @Override
     @NonNull
-    public ListenableFuture<StorageInfo> getStorageInfo() {
+    public ListenableFuture<StorageInfo> getStorageInfoAsync() {
         Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed");
         return execute(() -> mAppSearchImpl.getStorageInfoForDatabase(mPackageName, mDatabaseName));
     }
 
     @NonNull
     @Override
-    public ListenableFuture<Void> requestFlush() {
+    public ListenableFuture<Void> requestFlushAsync() {
         return execute(() -> {
             mAppSearchImpl.persistToDisk(PersistType.Code.FULL);
             return null;
@@ -472,20 +484,18 @@
     /**
      * Set schema to Icing for no-migration scenario.
      *
-     * <p>We only need one time {@link #setSchema} call for no-migration scenario by using the
+     * <p>We only need one time {@link #setSchemaAsync} call for no-migration scenario by using the
      * forceoverride in the request.
      */
     private SetSchemaResponse setSchemaNoMigrations(@NonNull SetSchemaRequest request,
-            @NonNull Map<String, List<PackageIdentifier>> copySchemasVisibleToPackages,
+            @NonNull List<VisibilityDocument> visibilityDocuments,
             SetSchemaStats.Builder setSchemaStatsBuilder)
             throws AppSearchException {
         SetSchemaResponse setSchemaResponse = mAppSearchImpl.setSchema(
                 mPackageName,
                 mDatabaseName,
                 new ArrayList<>(request.getSchemas()),
-                /*visibilityStore=*/ null,
-                new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
-                copySchemasVisibleToPackages,
+                visibilityDocuments,
                 request.isForceOverride(),
                 request.getVersion(),
                 setSchemaStatsBuilder);
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverter.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverter.java
index af24c98..e3c0a7da 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverter.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverter.java
@@ -17,7 +17,6 @@
 package androidx.appsearch.localstorage.converter;
 
 import static androidx.appsearch.localstorage.util.PrefixUtil.createPrefix;
-import static androidx.appsearch.localstorage.util.PrefixUtil.getDatabaseName;
 import static androidx.appsearch.localstorage.util.PrefixUtil.getPackageName;
 import static androidx.appsearch.localstorage.util.PrefixUtil.removePrefix;
 
@@ -28,7 +27,10 @@
 import androidx.annotation.RestrictTo;
 import androidx.appsearch.app.SearchSpec;
 import androidx.appsearch.exceptions.AppSearchException;
+import androidx.appsearch.localstorage.visibilitystore.CallerAccess;
+import androidx.appsearch.localstorage.visibilitystore.VisibilityChecker;
 import androidx.appsearch.localstorage.visibilitystore.VisibilityStore;
+import androidx.appsearch.localstorage.visibilitystore.VisibilityUtil;
 import androidx.collection.ArrayMap;
 import androidx.collection.ArraySet;
 import androidx.core.util.Preconditions;
@@ -152,36 +154,30 @@
      * For each target schema, we will check visibility store is that accessible to the caller. And
      * remove this schemas if it is not allowed for caller to query.
      *
-     * @param callerPackageName            The package name of caller
-     * @param visibilityStore              The visibility store which holds all visibility settings.
-     *                                     If you pass null, all schemas that don't belong to the
-     *                                     caller package will be removed.
-     * @param callerUid                    The uid of the caller.
-     * @param callerHasSystemAccess        Whether the caller has system access.
+     * @param callerAccess      Visibility access info of the calling app
+     * @param visibilityStore   The {@link VisibilityStore} that store all visibility
+     *                          information.
+     * @param visibilityChecker Optional visibility checker to check whether the caller
+     *                          could access target schemas. Pass {@code null} will
+     *                          reject access for all documents which doesn't belong
+     *                          to the calling package.
      */
-    public void removeInaccessibleSchemaFilter(@NonNull String callerPackageName,
+    public void removeInaccessibleSchemaFilter(
+            @NonNull CallerAccess callerAccess,
             @Nullable VisibilityStore visibilityStore,
-            int callerUid,
-            boolean callerHasSystemAccess) {
+            @Nullable VisibilityChecker visibilityChecker) {
         Iterator<String> targetPrefixedSchemaFilterIterator =
                 mTargetPrefixedSchemaFilters.iterator();
         while (targetPrefixedSchemaFilterIterator.hasNext()) {
             String targetPrefixedSchemaFilter = targetPrefixedSchemaFilterIterator.next();
             String packageName = getPackageName(targetPrefixedSchemaFilter);
 
-            boolean allow;
-            if (packageName.equals(callerPackageName)) {
-                // Callers can always retrieve their own data
-                allow = true;
-            } else if (visibilityStore == null) {
-                // If there's no visibility store, there's no extra access
-                allow = false;
-            } else {
-                String databaseName = getDatabaseName(targetPrefixedSchemaFilter);
-                allow = visibilityStore.isSchemaSearchableByCaller(packageName, databaseName,
-                        targetPrefixedSchemaFilter, callerUid, callerHasSystemAccess);
-            }
-            if (!allow) {
+            if (!VisibilityUtil.isSchemaSearchableByCaller(
+                    callerAccess,
+                    packageName,
+                    targetPrefixedSchemaFilter,
+                    visibilityStore,
+                    visibilityChecker)) {
                 targetPrefixedSchemaFilterIterator.remove();
             }
         }
@@ -229,7 +225,7 @@
                         ResultSpecProto.SnippetSpecProto.newBuilder()
                                 .setNumToSnippet(mSearchSpec.getSnippetCount())
                                 .setNumMatchesPerProperty(mSearchSpec.getSnippetCountPerProperty())
-                                .setMaxWindowBytes(mSearchSpec.getMaxSnippetSize()));
+                                .setMaxWindowUtf32Length(mSearchSpec.getMaxSnippetSize()));
 
         // Rewrites the typePropertyMasks that exist in {@code prefixes}.
         int groupingType = mSearchSpec.getResultGroupingTypeFlags();
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/CallStats.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/CallStats.java
index e3abf90..101ef1f 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/CallStats.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/CallStats.java
@@ -56,6 +56,7 @@
             CALL_TYPE_GLOBAL_SEARCH,
             CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH,
             CALL_TYPE_REMOVE_DOCUMENT_BY_SEARCH,
+            CALL_TYPE_GLOBAL_GET_DOCUMENT_BY_ID,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CallType {
@@ -76,6 +77,7 @@
     public static final int CALL_TYPE_GLOBAL_SEARCH = 12;
     public static final int CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH = 13;
     public static final int CALL_TYPE_REMOVE_DOCUMENT_BY_SEARCH = 14;
+    public static final int CALL_TYPE_GLOBAL_GET_DOCUMENT_BY_ID = 15;
 
     @Nullable
     private final String mPackageName;
@@ -145,11 +147,11 @@
      * Returns number of operations succeeded.
      *
      * <p>For example, for
-     * {@link androidx.appsearch.app.AppSearchSession#put}, it is the total number of individual
+     * {@link androidx.appsearch.app.AppSearchSession#putAsync}, it is the total number of individual
      * successful put operations. In this case, how many documents are successfully indexed.
      *
      * <p>For non-batch calls such as
-     * {@link androidx.appsearch.app.AppSearchSession#setSchema}, the sum of
+     * {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync}, the sum of
      * {@link CallStats#getNumOperationsSucceeded()} and
      * {@link CallStats#getNumOperationsFailed()} is always 1 since there is only one
      * operation.
@@ -162,11 +164,12 @@
      * Returns number of operations failed.
      *
      * <p>For example, for
-     * {@link androidx.appsearch.app.AppSearchSession#put}, it is the total number of individual
+     * {@link androidx.appsearch.app.AppSearchSession#putAsync}, it is the total number of individual
      * failed put operations. In this case, how many documents are failed to be indexed.
      *
-     * <p>For non-batch calls such as {@link androidx.appsearch.app.AppSearchSession#setSchema},
-     * the sum of {@link CallStats#getNumOperationsSucceeded()} and
+     * <p>For non-batch calls such as
+     * {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync}, the sum of
+     * {@link CallStats#getNumOperationsSucceeded()} and
      * {@link CallStats#getNumOperationsFailed()} is always 1 since there is only one
      * operation.
      */
@@ -235,12 +238,12 @@
          * Sets number of operations succeeded.
          *
          * <p>For example, for
-         * {@link androidx.appsearch.app.AppSearchSession#put}, it is the total number of
+         * {@link androidx.appsearch.app.AppSearchSession#putAsync}, it is the total number of
          * individual successful put operations. In this case, how many documents are
          * successfully indexed.
          *
          * <p>For non-batch calls such as
-         * {@link androidx.appsearch.app.AppSearchSession#setSchema}, the sum of
+         * {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync}, the sum of
          * {@link CallStats#getNumOperationsSucceeded()} and
          * {@link CallStats#getNumOperationsFailed()} is always 1 since there is only one
          * operation.
@@ -254,12 +257,12 @@
         /**
          * Sets number of operations failed.
          *
-         * <p>For example, for {@link androidx.appsearch.app.AppSearchSession#put}, it is the
+         * <p>For example, for {@link androidx.appsearch.app.AppSearchSession#putAsync}, it is the
          * total number of individual failed put operations. In this case, how many documents
          * are failed to be indexed.
          *
          * <p>For non-batch calls such as
-         * {@link androidx.appsearch.app.AppSearchSession#setSchema}, the sum of
+         * {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync}, the sum of
          * {@link CallStats#getNumOperationsSucceeded()} and
          * {@link CallStats#getNumOperationsFailed()} is always 1 since there is only one
          * operation.
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/PutDocumentStats.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/PutDocumentStats.java
index c8bc687..e9a25fd 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/PutDocumentStats.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/PutDocumentStats.java
@@ -23,7 +23,7 @@
 
 /**
  * A class for holding detailed stats to log for each individual document put by a
- * {@link androidx.appsearch.app.AppSearchSession#put} call.
+ * {@link androidx.appsearch.app.AppSearchSession#putAsync} call.
  *
  * @hide
  */
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/RemoveStats.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/RemoveStats.java
index 3a63aa0..7eb4820 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/RemoveStats.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/RemoveStats.java
@@ -29,8 +29,8 @@
 
 /**
  * Class holds detailed stats for
- * {@link androidx.appsearch.app.AppSearchSession#remove(RemoveByDocumentIdRequest)} and
- * {@link androidx.appsearch.app.AppSearchSession#remove(String, SearchSpec)}
+ * {@link androidx.appsearch.app.AppSearchSession#removeAsync(RemoveByDocumentIdRequest)} and
+ * {@link androidx.appsearch.app.AppSearchSession#removeAsync(String, SearchSpec)}
  *
  * @hide
  */
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/util/PrefixUtil.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/util/PrefixUtil.java
index 12d4587..cf0bde3 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/util/PrefixUtil.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/util/PrefixUtil.java
@@ -25,10 +25,13 @@
 import androidx.appsearch.exceptions.AppSearchException;
 
 import com.google.android.icing.proto.DocumentProto;
+import com.google.android.icing.proto.PropertyConfigProto;
 import com.google.android.icing.proto.PropertyProto;
+import com.google.android.icing.proto.SchemaTypeConfigProto;
 
 /**
  * Provides utility functions for working with package + database prefixes.
+ *
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -41,7 +44,8 @@
     @VisibleForTesting
     public static final char PACKAGE_DELIMITER = '$';
 
-    private PrefixUtil() {}
+    private PrefixUtil() {
+    }
 
     /**
      * Creates prefix string for given package name and database name.
@@ -50,6 +54,7 @@
     public static String createPrefix(@NonNull String packageName, @NonNull String databaseName) {
         return packageName + PACKAGE_DELIMITER + databaseName + DATABASE_DELIMITER;
     }
+
     /**
      * Creates prefix string for given package name.
      */
@@ -231,4 +236,37 @@
 
         return schemaPrefix;
     }
+
+    /**
+     * Removes any prefixes from types mentioned anywhere in {@code typeConfigBuilder}.
+     *
+     * @param typeConfigBuilder The schema type to mutate
+     * @return Prefix name that was removed from the schema type.
+     * @throws AppSearchException if there are unexpected database prefixing errors.
+     */
+    @NonNull
+    public static String removePrefixesFromSchemaType(
+            @NonNull SchemaTypeConfigProto.Builder typeConfigBuilder)
+            throws AppSearchException {
+        String typePrefix = PrefixUtil.getPrefix(typeConfigBuilder.getSchemaType());
+        // Rewrite SchemaProto.types.schema_type
+        String newSchemaType =
+                typeConfigBuilder.getSchemaType().substring(typePrefix.length());
+        typeConfigBuilder.setSchemaType(newSchemaType);
+
+        // Rewrite SchemaProto.types.properties.schema_type
+        for (int propertyIdx = 0;
+                propertyIdx < typeConfigBuilder.getPropertiesCount();
+                propertyIdx++) {
+            if (!typeConfigBuilder.getProperties(propertyIdx).getSchemaType().isEmpty()) {
+                PropertyConfigProto.Builder propertyConfigBuilder =
+                        typeConfigBuilder.getProperties(propertyIdx).toBuilder();
+                String newPropertySchemaType = propertyConfigBuilder.getSchemaType()
+                        .substring(typePrefix.length());
+                propertyConfigBuilder.setSchemaType(newPropertySchemaType);
+                typeConfigBuilder.setProperties(propertyIdx, propertyConfigBuilder);
+            }
+        }
+        return typePrefix;
+    }
 }
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/CallerAccess.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/CallerAccess.java
new file mode 100644
index 0000000..1a47109
--- /dev/null
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/CallerAccess.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2022 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.appsearch.localstorage.visibilitystore;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.core.util.Preconditions;
+
+/**
+ * Contains attributes of an API caller relevant to its access via visibility store.
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class CallerAccess {
+    private final String mCallingPackageName;
+
+    /**
+     * Constructs a new {@link CallerAccess}.
+     *
+     * @param callingPackageName    The name of the package which wants to access data.
+     */
+    public CallerAccess(@NonNull String callingPackageName) {
+        mCallingPackageName = Preconditions.checkNotNull(callingPackageName);
+    }
+
+    /** Returns the name of the package which wants to access data. */
+    @NonNull
+    public String getCallingPackageName() {
+        return mCallingPackageName;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (!(o instanceof CallerAccess)) return false;
+        CallerAccess that = (CallerAccess) o;
+        return mCallingPackageName.equals(that.mCallingPackageName);
+    }
+
+    @Override
+    public int hashCode() {
+        return mCallingPackageName.hashCode();
+    }
+}
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityChecker.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityChecker.java
new file mode 100644
index 0000000..7801562
--- /dev/null
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityChecker.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ * 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.appsearch.localstorage.visibilitystore;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+
+/**
+ * An interface for classes that validate document visibility data.
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public interface VisibilityChecker {
+    /**
+     * Checks whether the given caller has access to the given prefixed schemas.
+     *
+     * @param callerAccess      Visibility access info of the calling app
+     * @param packageName Package of app that owns the schemas.
+     * @param prefixedSchema The prefixed schema type that the caller want to access.
+     * @param visibilityStore The {@link VisibilityStore} that store all visibility information.
+     */
+    boolean isSchemaSearchableByCaller(
+            @NonNull CallerAccess callerAccess,
+            @NonNull String packageName,
+            @NonNull String prefixedSchema,
+            @NonNull VisibilityStore visibilityStore);
+}
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityDocumentV1.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityDocumentV1.java
new file mode 100644
index 0000000..537fd81
--- /dev/null
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityDocumentV1.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2022 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.appsearch.localstorage.visibilitystore;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.PackageIdentifier;
+import androidx.collection.ArraySet;
+import androidx.core.util.Preconditions;
+
+import java.util.Set;
+
+/**
+ * Holds the visibility settings in version 1 that apply to a schema type.
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class VisibilityDocumentV1 extends GenericDocument {
+    /**
+     * The Schema type for documents that hold AppSearch's metadata, e.g. visibility settings.
+     */
+    static final String SCHEMA_TYPE = "VisibilityType";
+    /** Namespace of documents that contain visibility settings */
+    static final String NAMESPACE = "";
+
+    /**
+     * Property that holds the list of platform-hidden schemas, as part of the visibility settings.
+     */
+    private static final String NOT_DISPLAYED_BY_SYSTEM_PROPERTY = "notPlatformSurfaceable";
+
+    /** Property that holds the package name that can access a schema. */
+    private static final String PACKAGE_NAME_PROPERTY = "packageName";
+
+    /** Property that holds the SHA 256 certificate of the app that can access a schema. */
+    private static final String SHA_256_CERT_PROPERTY = "sha256Cert";
+
+    /** Property that holds the role can access a schema. */
+    private static final String ROLE_PROPERTY = "role";
+
+    /** Property that holds the required permissions to access the schema. */
+    private static final String PERMISSION_PROPERTY = "permission";
+
+    /**
+     * Schema for the VisibilityStore's documents.
+     */
+    static final AppSearchSchema
+            SCHEMA = new AppSearchSchema.Builder(SCHEMA_TYPE)
+            .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                    NOT_DISPLAYED_BY_SYSTEM_PROPERTY)
+                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                    .build())
+            .addProperty(new AppSearchSchema.StringPropertyConfig.Builder(PACKAGE_NAME_PROPERTY)
+                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                    .build())
+            .addProperty(new AppSearchSchema.BytesPropertyConfig.Builder(SHA_256_CERT_PROPERTY)
+                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                    .build())
+            .addProperty(new AppSearchSchema.LongPropertyConfig.Builder(ROLE_PROPERTY)
+                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                    .build())
+            .addProperty(new AppSearchSchema.LongPropertyConfig.Builder(PERMISSION_PROPERTY)
+                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                    .build())
+            .build();
+
+    VisibilityDocumentV1(@NonNull GenericDocument genericDocument) {
+        super(genericDocument);
+    }
+
+    /** Returns whether this schema is visible to the system. */
+    boolean isNotDisplayedBySystem() {
+        return getPropertyBoolean(NOT_DISPLAYED_BY_SYSTEM_PROPERTY);
+    }
+
+    /**
+     * Returns a package name array which could access this schema. Use {@link #getSha256Certs()}
+     * to get package's sha 256 certs. The same index of package names array and sha256Certs array
+     * represents same package.
+     */
+    @NonNull
+    String[] getPackageNames() {
+        return getPropertyStringArray(PACKAGE_NAME_PROPERTY);
+    }
+
+    /**
+     * Returns a package sha256Certs array which could access this schema. Use
+     * {@link #getPackageNames()} to get package's name. The same index of package names array
+     * and sha256Certs array represents same package.
+     */
+    @NonNull
+    byte[][] getSha256Certs() {
+        return getPropertyBytesArray(SHA_256_CERT_PROPERTY);
+    }
+
+    /**
+     * Returns an array of Android Roles that have access to the schema this
+     * {@link VisibilityDocumentV1} represents.
+     */
+    @Nullable
+    Set<Integer> getVisibleToRoles() {
+        return toInts(getPropertyLongArray(ROLE_PROPERTY));
+    }
+
+    /**
+     * Returns an array of Android Permissions that caller mush hold to access the schema
+     * this {@link VisibilityDocumentV1} represents.
+     */
+    @Nullable
+    Set<Integer> getVisibleToPermissions() {
+        return toInts(getPropertyLongArray(PERMISSION_PROPERTY));
+    }
+
+    /** Builder for {@link VisibilityDocumentV1}. */
+    static class Builder extends GenericDocument.Builder<Builder> {
+        private final Set<PackageIdentifier> mPackageIdentifiers = new ArraySet<>();
+
+        /**
+         * Creates a {@link Builder} for a {@link VisibilityDocumentV1}.
+         *
+         * @param id The SchemaType of the {@link AppSearchSchema} that this
+         *           {@link VisibilityDocumentV1} represents. The package and database prefix will
+         *           be added in server side. We are using prefixed schema type to be the final
+         *           id of this {@link VisibilityDocumentV1}.
+         */
+        Builder(@NonNull String id) {
+            super(NAMESPACE, id, SCHEMA_TYPE);
+        }
+
+        /** Sets whether this schema has opted out of platform surfacing. */
+        @NonNull
+        Builder setNotDisplayedBySystem(boolean notDisplayedBySystem) {
+            return setPropertyBoolean(NOT_DISPLAYED_BY_SYSTEM_PROPERTY,
+                    notDisplayedBySystem);
+        }
+
+        /** Add {@link PackageIdentifier} of packages which has access to this schema. */
+        @NonNull
+        Builder addVisibleToPackages(@NonNull Set<PackageIdentifier> packageIdentifiers) {
+            Preconditions.checkNotNull(packageIdentifiers);
+            mPackageIdentifiers.addAll(packageIdentifiers);
+            return this;
+        }
+
+        /** Add {@link PackageIdentifier} of packages which has access to this schema. */
+        @NonNull
+        Builder addVisibleToPackage(@NonNull PackageIdentifier packageIdentifier) {
+            Preconditions.checkNotNull(packageIdentifier);
+            mPackageIdentifiers.add(packageIdentifier);
+            return this;
+        }
+
+        /** Add a set of Android role that has access to the schema this
+         * {@link VisibilityDocumentV1} represents. */
+        @NonNull
+        Builder setVisibleToRoles(@NonNull Set<Integer> visibleToRoles) {
+            Preconditions.checkNotNull(visibleToRoles);
+            setPropertyLong(ROLE_PROPERTY, toLongs(visibleToRoles));
+            return this;
+        }
+
+        /** Add a set of Android role that has access to the schema this
+         * {@link VisibilityDocumentV1} represents. */
+        @NonNull
+        Builder setVisibleToPermissions(@NonNull Set<Integer> visibleToPermissions) {
+            Preconditions.checkNotNull(visibleToPermissions);
+            setPropertyLong(PERMISSION_PROPERTY, toLongs(visibleToPermissions));
+            return this;
+        }
+
+        /** Build a {@link VisibilityDocumentV1} */
+        @Override
+        @NonNull
+        public VisibilityDocumentV1 build() {
+            String[] packageNames = new String[mPackageIdentifiers.size()];
+            byte[][] sha256Certs = new byte[mPackageIdentifiers.size()][32];
+            int i = 0;
+            for (PackageIdentifier packageIdentifier : mPackageIdentifiers) {
+                packageNames[i] = packageIdentifier.getPackageName();
+                sha256Certs[i] = packageIdentifier.getSha256Certificate();
+                ++i;
+            }
+            setPropertyString(PACKAGE_NAME_PROPERTY, packageNames);
+            setPropertyBytes(SHA_256_CERT_PROPERTY, sha256Certs);
+            return new VisibilityDocumentV1(super.build());
+        }
+    }
+
+    @NonNull
+    static long[] toLongs(@NonNull Set<Integer> properties) {
+        long[] outputs = new long[properties.size()];
+        int i = 0;
+        for (int property : properties) {
+            outputs[i++] = property;
+        }
+        return outputs;
+    }
+
+    @Nullable
+    private static Set<Integer> toInts(@Nullable long[] properties) {
+        if (properties == null) {
+            return null;
+        }
+        Set<Integer> outputs = new ArraySet<>(properties.length);
+        for (long property : properties) {
+            outputs.add((int) property);
+        }
+        return outputs;
+    }
+}
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStore.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStore.java
index d3d754e..767d17a 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStore.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStore.java
@@ -15,60 +15,254 @@
  */
 package androidx.appsearch.localstorage.visibilitystore;
 
-import androidx.annotation.NonNull;
-import androidx.annotation.RestrictTo;
-import androidx.annotation.VisibleForTesting;
-import androidx.appsearch.app.PackageIdentifier;
-import androidx.appsearch.exceptions.AppSearchException;
+import static androidx.appsearch.app.AppSearchResult.RESULT_NOT_FOUND;
 
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.AppSearchResult;
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.GetSchemaResponse;
+import androidx.appsearch.app.VisibilityDocument;
+import androidx.appsearch.app.VisibilityPermissionDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import androidx.appsearch.localstorage.AppSearchImpl;
+import androidx.appsearch.localstorage.util.PrefixUtil;
+import androidx.collection.ArrayMap;
+import androidx.core.util.Preconditions;
+
+import com.google.android.icing.proto.PersistType;
+
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 /**
- * An interface for classes that store and validate document visibility data.
+ * Stores all visibility settings for all databases that AppSearchImpl knows about.
+ * Persists the visibility settings and reloads them on initialization.
+ *
+ * <p>The VisibilityStore creates a {@link VisibilityDocument} for each schema. This document holds
+ * the visibility settings that apply to that schema. The VisibilityStore also creates a
+ * schema for these documents and has its own package and database so that its data doesn't
+ * interfere with any clients' data. It persists the document and schema through AppSearchImpl.
+ *
+ * <p>These visibility settings won't be used in AppSearch Jetpack, we only store them for clients
+ * to look up.
  *
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-public interface VisibilityStore {
+public class VisibilityStore {
+    private static final String TAG = "AppSearchVisibilityStor";
     /**
      * These cannot have any of the special characters used by AppSearchImpl (e.g. {@code
      * AppSearchImpl#PACKAGE_DELIMITER} or {@code AppSearchImpl#DATABASE_DELIMITER}.
      */
-    String PACKAGE_NAME = "VS#Pkg";
+    public static final String VISIBILITY_PACKAGE_NAME = "VS#Pkg";
 
-    @VisibleForTesting
-    String DATABASE_NAME = "VS#Db";
+    public static final String VISIBILITY_DATABASE_NAME = "VS#Db";
 
     /**
-     * Sets visibility settings for the given database. Any previous visibility settings will be
-     * overwritten.
+     * Map of PrefixedSchemaType and VisibilityDocument stores visibility information for each
+     * schema type.
+     */
+    private final Map<String, VisibilityDocument> mVisibilityDocumentMap = new ArrayMap<>();
+
+    private final AppSearchImpl mAppSearchImpl;
+
+    public VisibilityStore(@NonNull AppSearchImpl appSearchImpl)
+            throws AppSearchException {
+        mAppSearchImpl = Preconditions.checkNotNull(appSearchImpl);
+
+        GetSchemaResponse getSchemaResponse = mAppSearchImpl.getSchema(
+                VISIBILITY_PACKAGE_NAME,
+                VISIBILITY_DATABASE_NAME,
+                new CallerAccess(/*callingPackageName=*/VISIBILITY_PACKAGE_NAME));
+        List<VisibilityDocumentV1> visibilityDocumentsV1s = null;
+        switch (getSchemaResponse.getVersion()) {
+            case VisibilityDocument.SCHEMA_VERSION_DOC_PER_PACKAGE:
+                // TODO (b/202194495) add VisibilityDocument in version 0 back instead of using
+                //  GenericDocument.
+                List<GenericDocument> visibilityDocumentsV0s =
+                        VisibilityStoreMigrationHelperFromV0.getVisibilityDocumentsInVersion0(
+                                getSchemaResponse, mAppSearchImpl);
+                visibilityDocumentsV1s = VisibilityStoreMigrationHelperFromV0
+                        .toVisibilityDocumentV1(visibilityDocumentsV0s);
+                // fall through
+            case VisibilityDocument.SCHEMA_VERSION_DOC_PER_SCHEMA:
+                if (visibilityDocumentsV1s == null) {
+                    // We need to read VisibilityDocument in Version 1 from AppSearch instead of
+                    // taking from the above step.
+                    visibilityDocumentsV1s =
+                            VisibilityStoreMigrationHelperFromV1.getVisibilityDocumentsInVersion1(
+                                    mAppSearchImpl);
+                }
+                setLatestSchemaAndDocuments(VisibilityStoreMigrationHelperFromV1
+                        .toVisibilityDocumentsV2(visibilityDocumentsV1s));
+                break;
+            case VisibilityDocument.SCHEMA_VERSION_LATEST:
+                Set<AppSearchSchema> existingVisibilitySchema = getSchemaResponse.getSchemas();
+                if (existingVisibilitySchema.contains(VisibilityDocument.SCHEMA)
+                        && existingVisibilitySchema.contains(VisibilityPermissionDocument.SCHEMA)) {
+                    // The latest Visibility schema is in AppSearch, we must find our schema type.
+                    // Extract all stored Visibility Document into mVisibilityDocumentMap.
+                    loadVisibilityDocumentMap();
+                } else {
+                    // We must have a broken schema. Reset it to the latest version.
+                    // Do NOT set forceOverride to be true here. If you hit problem here it means
+                    // you made a incompatible change in Visibility Schema without update the
+                    // version number. You should bump the version number and create a
+                    // VisibilityStoreMigrationHelper which can analyse the different between the
+                    // old version and the new version to migration user's visibility settings.
+                    mAppSearchImpl.setSchema(
+                            VISIBILITY_PACKAGE_NAME,
+                            VISIBILITY_DATABASE_NAME,
+                            Arrays.asList(VisibilityDocument.SCHEMA,
+                                    VisibilityPermissionDocument.SCHEMA),
+                            /*visibilityDocuments=*/ Collections.emptyList(),
+                            /*forceOverride=*/ false,
+                            /*version=*/ VisibilityDocument.SCHEMA_VERSION_LATEST,
+                            /*setSchemaStatsBuilder=*/ null);
+                }
+                break;
+            default:
+                // We must did something wrong.
+                throw new AppSearchException(AppSearchResult.RESULT_INTERNAL_ERROR,
+                        "Found unsupported visibility version: " + getSchemaResponse.getVersion());
+        }
+    }
+
+    /**
+     * Sets visibility settings for the given {@link VisibilityDocument}s. Any previous
+     * {@link VisibilityDocument}s with same prefixed schema type will be overwritten.
      *
-     * @param packageName Package of app that owns the schemas.
-     * @param databaseName Database that owns the schemas.
-     * @param schemasNotDisplayedBySystem Set of prefixed schemas that should be hidden from
-     *     platform surfaces.
-     * @param schemasVisibleToPackages Map of prefixed schemas to a list of package identifiers that
-     *     have access to the schema.
+     * @param prefixedVisibilityDocuments List of prefixed {@link VisibilityDocument} which
+     *                                    contains schema type's visibility information.
      * @throws AppSearchException on AppSearchImpl error.
      */
-    void setVisibility(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull Set<String> schemasNotDisplayedBySystem,
-            @NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages)
-            throws AppSearchException;
+    public void setVisibility(@NonNull List<VisibilityDocument> prefixedVisibilityDocuments)
+            throws AppSearchException {
+        Preconditions.checkNotNull(prefixedVisibilityDocuments);
+        // Save new setting.
+        for (int i = 0; i < prefixedVisibilityDocuments.size(); i++) {
+            // put VisibilityDocument to AppSearchImpl and mVisibilityDocumentMap. If there is a
+            // VisibilityDocument with same prefixed schema exists, it will be replaced by new
+            // VisibilityDocument in both AppSearch and memory look up map.
+            VisibilityDocument prefixedVisibilityDocument = prefixedVisibilityDocuments.get(i);
+            mAppSearchImpl.putDocument(
+                    VISIBILITY_PACKAGE_NAME,
+                    VISIBILITY_DATABASE_NAME,
+                    prefixedVisibilityDocument,
+                    /*sendChangeNotifications=*/ false,
+                    /*logger=*/ null);
+            mVisibilityDocumentMap.put(prefixedVisibilityDocument.getId(),
+                    prefixedVisibilityDocument);
+        }
+        // Now that the visibility document has been written. Persist the newly written data.
+        mAppSearchImpl.persistToDisk(PersistType.Code.LITE);
+    }
 
     /**
-     * Checks whether the given package has access to system-surfaceable schemas.
-     *
-     * @param callerUid UID of the app that wants to see the data.
+     * Remove the visibility setting for the given prefixed schema type from both AppSearch and
+     * memory look up map.
      */
-    boolean isSchemaSearchableByCaller(
-            @NonNull String packageName,
-            @NonNull String databaseName,
-            @NonNull String prefixedSchema,
-            int callerUid,
-            boolean callerHasSystemAccess);
+    public void removeVisibility(@NonNull Set<String> prefixedSchemaTypes)
+            throws AppSearchException {
+        for (String prefixedSchemaType : prefixedSchemaTypes) {
+            if (mVisibilityDocumentMap.remove(prefixedSchemaType) != null) {
+                // The deleted schema is not all-default setting, we need to remove its
+                // VisibilityDocument from Icing.
+                try {
+                    mAppSearchImpl.remove(VISIBILITY_PACKAGE_NAME, VISIBILITY_DATABASE_NAME,
+                            VisibilityDocument.NAMESPACE, prefixedSchemaType,
+                            /*removeStatsBuilder=*/null);
+                } catch (AppSearchException e) {
+                    if (e.getResultCode() == RESULT_NOT_FOUND) {
+                        // We are trying to remove this visibility setting, so it's weird but seems
+                        // to be fine if we cannot find it.
+                        Log.e(TAG, "Cannot find visibility document for " + prefixedSchemaType
+                                + " to remove.");
+                        return;
+                    }
+                    throw e;
+                }
+            }
+        }
+    }
+
+    /** Gets the {@link VisibilityDocument} for the given prefixed schema type.     */
+    @Nullable
+    public VisibilityDocument getVisibility(@NonNull String prefixedSchemaType) {
+        return mVisibilityDocumentMap.get(prefixedSchemaType);
+    }
+
+    /**
+     * Loads all stored latest {@link VisibilityDocument} from Icing, and put them into
+     * {@link #mVisibilityDocumentMap}.
+     */
+    private void loadVisibilityDocumentMap() throws AppSearchException {
+        // Populate visibility settings set
+        List<String> cachedSchemaTypes = mAppSearchImpl.getAllPrefixedSchemaTypes();
+        for (int i = 0; i < cachedSchemaTypes.size(); i++) {
+            String prefixedSchemaType = cachedSchemaTypes.get(i);
+            String packageName = PrefixUtil.getPackageName(prefixedSchemaType);
+            if (packageName.equals(VISIBILITY_PACKAGE_NAME)) {
+                continue; // Our own package. Skip.
+            }
+
+            VisibilityDocument visibilityDocument;
+            try {
+                // Note: We use the other clients' prefixed schema type as ids
+                visibilityDocument = new VisibilityDocument(
+                        mAppSearchImpl.getDocument(
+                                VISIBILITY_PACKAGE_NAME,
+                                VISIBILITY_DATABASE_NAME,
+                                VisibilityDocument.NAMESPACE,
+                                /*id=*/ prefixedSchemaType,
+                                /*typePropertyPaths=*/ Collections.emptyMap()));
+            } catch (AppSearchException e) {
+                if (e.getResultCode() == RESULT_NOT_FOUND) {
+                    // The schema has all default setting and we won't have a VisibilityDocument for
+                    // it.
+                    continue;
+                }
+                // Otherwise, this is some other error we should pass up.
+                throw e;
+            }
+            mVisibilityDocumentMap.put(prefixedSchemaType, visibilityDocument);
+        }
+    }
+
+    /**
+     * Set the latest version of {@link VisibilityDocument} and its schema to AppSearch.
+     */
+    private void setLatestSchemaAndDocuments(@NonNull List<VisibilityDocument> migratedDocuments)
+            throws AppSearchException {
+        // The latest schema type doesn't exist yet. Add it. Set forceOverride true to
+        // delete old schema.
+        mAppSearchImpl.setSchema(
+                VISIBILITY_PACKAGE_NAME,
+                VISIBILITY_DATABASE_NAME,
+                Arrays.asList(VisibilityDocument.SCHEMA,
+                        VisibilityPermissionDocument.SCHEMA),
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ true,
+                /*version=*/ VisibilityDocument.SCHEMA_VERSION_LATEST,
+                /*setSchemaStatsBuilder=*/ null);
+        for (int i = 0; i < migratedDocuments.size(); i++) {
+            VisibilityDocument migratedDocument = migratedDocuments.get(i);
+            mVisibilityDocumentMap.put(migratedDocument.getId(), migratedDocument);
+            mAppSearchImpl.putDocument(
+                    VISIBILITY_PACKAGE_NAME,
+                    VISIBILITY_DATABASE_NAME,
+                    migratedDocument,
+                    /*sendChangeNotifications=*/ false,
+                    /*logger=*/ null);
+        }
+    }
 }
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0.java
new file mode 100644
index 0000000..edff437
--- /dev/null
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2022 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.appsearch.localstorage.visibilitystore;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.annotation.VisibleForTesting;
+import androidx.appsearch.app.AppSearchResult;
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.GetSchemaResponse;
+import androidx.appsearch.app.PackageIdentifier;
+import androidx.appsearch.app.VisibilityDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import androidx.appsearch.localstorage.AppSearchImpl;
+import androidx.appsearch.localstorage.util.PrefixUtil;
+import androidx.collection.ArrayMap;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The helper class to store Visibility Document information of version 0 and handle the upgrade to
+ * version 1.
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class VisibilityStoreMigrationHelperFromV0 {
+    private VisibilityStoreMigrationHelperFromV0() {}
+    /** Prefix to add to all visibility document ids. IcingSearchEngine doesn't allow empty ids. */
+    private static final String DEPRECATED_ID_PREFIX = "uri:";
+
+    /** Schema type for documents that hold AppSearch's metadata, e.g. visibility settings */
+    @VisibleForTesting
+    static final String DEPRECATED_VISIBILITY_SCHEMA_TYPE = "VisibilityType";
+
+    /**
+     * Property that holds the list of platform-hidden schemas, as part of the visibility settings.
+     */
+    @VisibleForTesting
+    static final String DEPRECATED_NOT_DISPLAYED_BY_SYSTEM_PROPERTY =
+            "notPlatformSurfaceable";
+
+    /** Property that holds nested documents of package accessible schemas. */
+    @VisibleForTesting
+    static final String DEPRECATED_VISIBLE_TO_PACKAGES_PROPERTY = "packageAccessible";
+
+    /**
+     * Property that holds the list of platform-hidden schemas, as part of the visibility settings.
+     */
+    @VisibleForTesting
+    static final String DEPRECATED_PACKAGE_SCHEMA_TYPE = "PackageAccessibleType";
+
+    /** Property that holds the prefixed schema type that is accessible by some package. */
+    @VisibleForTesting
+    static final String DEPRECATED_ACCESSIBLE_SCHEMA_PROPERTY = "accessibleSchema";
+
+    /** Property that holds the package name that can access a schema. */
+    @VisibleForTesting
+    static final String DEPRECATED_PACKAGE_NAME_PROPERTY = "packageName";
+
+    /** Property that holds the SHA 256 certificate of the app that can access a schema. */
+    @VisibleForTesting
+    static final String DEPRECATED_SHA_256_CERT_PROPERTY = "sha256Cert";
+
+//    The visibility schema of version 0.
+//---------------------------------------------------------------------------------------------
+//    Schema of DEPRECATED_VISIBILITY_SCHEMA_TYPE:
+//    new AppSearchSchema.Builder(
+//            DEPRECATED_VISIBILITY_SCHEMA_TYPE)
+//            .addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
+//                    DEPRECATED_NOT_DISPLAYED_BY_SYSTEM_PROPERTY)
+//                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+//                    .build())
+//            .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(
+//                    DEPRECATED_VISIBLE_TO_PACKAGES_PROPERTY,
+//                    DEPRECATED_PACKAGE_SCHEMA_TYPE)
+//                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+//                    .build())
+//            .build();
+//    Schema of DEPRECATED_PACKAGE_SCHEMA_TYPE:
+//    new AppSearchSchema.Builder(DEPRECATED_PACKAGE_SCHEMA_TYPE)
+//        .addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
+//                 DEPRECATED_PACKAGE_NAME_PROPERTY)
+//                .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+//                .build())
+//        .addProperty(new AppSearchSchema.BytesPropertyConfig.Builder(
+//                DEPRECATED_SHA_256_CERT_PROPERTY)
+//                .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+//                .build())
+//        .addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
+//                DEPRECATED_ACCESSIBLE_SCHEMA_PROPERTY)
+//                .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+//                .build())
+//        .build();
+//---------------------------------------------------------------------------------------------
+
+    /** Returns whether the given schema type is deprecated.     */
+    static boolean isDeprecatedType(@NonNull String schemaType) {
+        return schemaType.equals(DEPRECATED_VISIBILITY_SCHEMA_TYPE)
+                || schemaType.equals(DEPRECATED_PACKAGE_SCHEMA_TYPE);
+    }
+
+    /**
+     * Adds a prefix to create a deprecated visibility document's id.
+     *
+     * @param packageName Package to which the visibility doc refers.
+     * @param databaseName Database to which the visibility doc refers.
+     * @return deprecated visibility document's id.
+     */
+    @NonNull
+    static String getDeprecatedVisibilityDocumentId(
+            @NonNull String packageName, @NonNull String databaseName) {
+        return DEPRECATED_ID_PREFIX + PrefixUtil.createPrefix(packageName, databaseName);
+    }
+
+    /**  Reads all stored deprecated Visibility Document in version 0 from icing. */
+    static List<GenericDocument> getVisibilityDocumentsInVersion0(
+            @NonNull GetSchemaResponse getSchemaResponse,
+            @NonNull AppSearchImpl appSearchImpl) throws AppSearchException {
+        if (!hasDeprecatedType(getSchemaResponse)) {
+            return new ArrayList<>();
+        }
+        Map<String, Set<String>> packageToDatabases = appSearchImpl.getPackageToDatabases();
+        List<GenericDocument> deprecatedDocuments = new ArrayList<>(packageToDatabases.size());
+        for (Map.Entry<String, Set<String>> entry : packageToDatabases.entrySet()) {
+            String packageName = entry.getKey();
+            if (packageName.equals(VisibilityStore.VISIBILITY_PACKAGE_NAME)) {
+                continue; // Our own package. Skip.
+            }
+            for (String databaseName : entry.getValue()) {
+                try {
+                    // Note: We use the other clients' prefixed names as ids
+                    deprecatedDocuments.add(appSearchImpl.getDocument(
+                            VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                            VisibilityStore.VISIBILITY_DATABASE_NAME,
+                            VisibilityDocument.NAMESPACE,
+                            getDeprecatedVisibilityDocumentId(packageName, databaseName),
+                            /*typePropertyPaths=*/ Collections.emptyMap()));
+                } catch (AppSearchException e) {
+                    if (e.getResultCode() == AppSearchResult.RESULT_NOT_FOUND) {
+                        // TODO(b/172068212): This indicates some desync error. We were expecting a
+                        //  document, but didn't find one. Should probably reset AppSearch instead
+                        //  of ignoring it.
+                        continue;
+                    }
+                    // Otherwise, this is some other error we should pass up.
+                    throw e;
+                }
+            }
+        }
+        return deprecatedDocuments;
+    }
+
+    /**
+     * Converts the given list of deprecated Visibility Documents into a Map of {@code
+     * <PrefixedSchemaType, VisibilityDocument.Builder of the latest version>}.
+     *
+     * @param visibilityDocumentV0s          The deprecated Visibility Document we found.
+     */
+    @NonNull
+    static List<VisibilityDocumentV1> toVisibilityDocumentV1(
+            @NonNull List<GenericDocument> visibilityDocumentV0s) {
+        Map<String, VisibilityDocumentV1.Builder> documentBuilderMap = new ArrayMap<>();
+
+        // Set all visibility information into documentBuilderMap
+        for (int i = 0; i < visibilityDocumentV0s.size(); i++) {
+            GenericDocument visibilityDocumentV0 = visibilityDocumentV0s.get(i);
+
+            // Read not displayed by system property field.
+            String[] notDisplayedBySystemSchemas = visibilityDocumentV0.getPropertyStringArray(
+                    DEPRECATED_NOT_DISPLAYED_BY_SYSTEM_PROPERTY);
+            if (notDisplayedBySystemSchemas != null) {
+                for (String notDisplayedBySystemSchema : notDisplayedBySystemSchemas) {
+                    // SetSchemaRequest.Builder.build() make sure all schemas that has visibility
+                    // setting must present in the requests.
+                    VisibilityDocumentV1.Builder visibilityBuilder = getOrCreateBuilder(
+                            documentBuilderMap, notDisplayedBySystemSchema);
+                    visibilityBuilder.setNotDisplayedBySystem(true);
+                }
+            }
+
+            // Read visible to packages field.
+            GenericDocument[] deprecatedPackageDocuments = visibilityDocumentV0
+                    .getPropertyDocumentArray(DEPRECATED_VISIBLE_TO_PACKAGES_PROPERTY);
+            if (deprecatedPackageDocuments != null) {
+                for (GenericDocument deprecatedPackageDocument : deprecatedPackageDocuments) {
+                    String prefixedSchemaType = deprecatedPackageDocument
+                            .getPropertyString(DEPRECATED_ACCESSIBLE_SCHEMA_PROPERTY);
+                    VisibilityDocumentV1.Builder visibilityBuilder = getOrCreateBuilder(
+                            documentBuilderMap, prefixedSchemaType);
+                    visibilityBuilder.addVisibleToPackage(new PackageIdentifier(
+                            deprecatedPackageDocument.getPropertyString(
+                                    DEPRECATED_PACKAGE_NAME_PROPERTY),
+                            deprecatedPackageDocument.getPropertyBytes(
+                                    DEPRECATED_SHA_256_CERT_PROPERTY)));
+                }
+            }
+        }
+        List<VisibilityDocumentV1> visibilityDocumentsV1 =
+                new ArrayList<>(documentBuilderMap.size());
+        for (Map.Entry<String, VisibilityDocumentV1.Builder> entry :
+                documentBuilderMap.entrySet()) {
+            visibilityDocumentsV1.add(entry.getValue().build());
+        }
+        return visibilityDocumentsV1;
+    }
+
+    /**
+     * Return whether the database maybe has the oldest version of deprecated schema.
+     *
+     * <p> Since the current version number is 0, it is possible that the database is just empty
+     * and it return 0 as the default version number. So we need to check if the deprecated document
+     * presents to trigger the migration.
+     */
+    private static boolean hasDeprecatedType(@NonNull GetSchemaResponse getSchemaResponse) {
+        for (AppSearchSchema schema : getSchemaResponse.getSchemas()) {
+            if (VisibilityStoreMigrationHelperFromV0
+                    .isDeprecatedType(schema.getSchemaType())) {
+                // Found deprecated type, we need to migrate visibility Document. And it's
+                // not possible for us to find the latest visibility schema.
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @NonNull
+    private static VisibilityDocumentV1.Builder getOrCreateBuilder(
+            @NonNull Map<String, VisibilityDocumentV1.Builder> documentBuilderMap,
+            @NonNull String schemaType) {
+        VisibilityDocumentV1.Builder builder = documentBuilderMap.get(schemaType);
+        if (builder == null) {
+            builder = new VisibilityDocumentV1.Builder(/*id=*/ schemaType);
+            documentBuilderMap.put(schemaType, builder);
+        }
+        return builder;
+    }
+}
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1.java
new file mode 100644
index 0000000..cd3e2c5
--- /dev/null
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2022 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.appsearch.localstorage.visibilitystore;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.annotation.VisibleForTesting;
+import androidx.appsearch.app.AppSearchResult;
+import androidx.appsearch.app.PackageIdentifier;
+import androidx.appsearch.app.SetSchemaRequest;
+import androidx.appsearch.app.VisibilityDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import androidx.appsearch.localstorage.AppSearchImpl;
+import androidx.appsearch.localstorage.util.PrefixUtil;
+import androidx.collection.ArraySet;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * The helper class to store Visibility Document information of version 1 and handle the upgrade to
+ * latest version
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class VisibilityStoreMigrationHelperFromV1 {
+    private VisibilityStoreMigrationHelperFromV1() {}
+
+    /** Enum in {@link androidx.appsearch.app.SetSchemaRequest} AppSearch supported role. */
+    @VisibleForTesting
+    static final int DEPRECATED_ROLE_HOME = 1;
+
+    /** Enum in {@link androidx.appsearch.app.SetSchemaRequest} AppSearch supported role. */
+    @VisibleForTesting
+    static final int DEPRECATED_ROLE_ASSISTANT = 2;
+
+    /**  Reads all stored deprecated Visibility Document in version 0 from icing. */
+    static List<VisibilityDocumentV1> getVisibilityDocumentsInVersion1(
+            @NonNull AppSearchImpl appSearchImpl) throws AppSearchException {
+        List<String> allPrefixedSchemaTypes = appSearchImpl.getAllPrefixedSchemaTypes();
+        List<VisibilityDocumentV1> visibilityDocumentV1s =
+                new ArrayList<>(allPrefixedSchemaTypes.size());
+        for (int i = 0; i < allPrefixedSchemaTypes.size(); i++) {
+            String packageName = PrefixUtil.getPackageName(allPrefixedSchemaTypes.get(i));
+            if (packageName.equals(VisibilityStore.VISIBILITY_PACKAGE_NAME)) {
+                continue; // Our own package. Skip.
+            }
+            try {
+                // Note: We use the prefixed schema type as ids
+                visibilityDocumentV1s.add(new VisibilityDocumentV1(appSearchImpl.getDocument(
+                        VisibilityStore.VISIBILITY_PACKAGE_NAME,
+                        VisibilityStore.VISIBILITY_DATABASE_NAME,
+                        VisibilityDocument.NAMESPACE,
+                        allPrefixedSchemaTypes.get(i),
+                        /*typePropertyPaths=*/ Collections.emptyMap())));
+            } catch (AppSearchException e) {
+                if (e.getResultCode() == AppSearchResult.RESULT_NOT_FOUND) {
+                    // TODO(b/172068212): This indicates some desync error. We were expecting a
+                    //  document, but didn't find one. Should probably reset AppSearch instead
+                    //  of ignoring it.
+                    continue;
+                }
+                // Otherwise, this is some other error we should pass up.
+                throw e;
+            }
+        }
+        return visibilityDocumentV1s;
+    }
+
+    /**
+     * Converts the given list of deprecated Visibility Documents into a Map of {@code
+     * <PrefixedSchemaType, VisibilityDocument.Builder of the latest version>}.
+     *
+     * @param visibilityDocumentV1s          The deprecated Visibility Document we found.
+     */
+    @NonNull
+    static List<VisibilityDocument> toVisibilityDocumentsV2(
+            @NonNull List<VisibilityDocumentV1> visibilityDocumentV1s) {
+        List<VisibilityDocument> latestVisibilityDocuments =
+                new ArrayList<>(visibilityDocumentV1s.size());
+        for (int i = 0; i < visibilityDocumentV1s.size(); i++) {
+            VisibilityDocumentV1 visibilityDocumentV1 = visibilityDocumentV1s.get(i);
+            Set<Set<Integer>> visibleToPermissions = new ArraySet<>();
+            Set<Integer> deprecatedVisibleToRoles = visibilityDocumentV1.getVisibleToRoles();
+            if (deprecatedVisibleToRoles != null) {
+                for (int deprecatedVisibleToRole : deprecatedVisibleToRoles) {
+                    Set<Integer> visibleToPermission = new ArraySet<>();
+                    switch (deprecatedVisibleToRole) {
+                        case DEPRECATED_ROLE_HOME:
+                            visibleToPermission.add(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA);
+                            break;
+                        case DEPRECATED_ROLE_ASSISTANT:
+                            visibleToPermission.add(SetSchemaRequest
+                                    .READ_ASSISTANT_APP_SEARCH_DATA);
+                            break;
+                    }
+                    visibleToPermissions.add(visibleToPermission);
+                }
+            }
+            Set<Integer> deprecatedVisibleToPermissions =
+                    visibilityDocumentV1.getVisibleToPermissions();
+            if (deprecatedVisibleToPermissions != null) {
+                visibleToPermissions.add(deprecatedVisibleToPermissions);
+            }
+
+            Set<PackageIdentifier> packageIdentifiers = new ArraySet<>();
+            String[] packageNames = visibilityDocumentV1.getPackageNames();
+            byte[][] sha256Certs = visibilityDocumentV1.getSha256Certs();
+            if (packageNames.length == sha256Certs.length) {
+                for (int j = 0; j < packageNames.length; j++) {
+                    packageIdentifiers.add(new PackageIdentifier(packageNames[j], sha256Certs[j]));
+                }
+            }
+            VisibilityDocument.Builder latestVisibilityDocumentBuilder =
+                    new VisibilityDocument.Builder(visibilityDocumentV1.getId())
+                    .setNotDisplayedBySystem(visibilityDocumentV1.isNotDisplayedBySystem())
+                    .addVisibleToPackages(packageIdentifiers);
+            if (!visibleToPermissions.isEmpty()) {
+                latestVisibilityDocumentBuilder.setVisibleToPermissions(visibleToPermissions);
+            }
+            latestVisibilityDocuments.add(latestVisibilityDocumentBuilder.build());
+        }
+        return latestVisibilityDocuments;
+    }
+}
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityUtil.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityUtil.java
new file mode 100644
index 0000000..ea04968
--- /dev/null
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityUtil.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2022 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.appsearch.localstorage.visibilitystore;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.core.util.Preconditions;
+
+/**
+ * Utilities for working with {@link VisibilityChecker} and {@link VisibilityStore}.
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class VisibilityUtil {
+    private VisibilityUtil() {}
+
+    /**
+     * Determines whether the calling package has access to the given prefixed schema type.
+     *
+     * <p>Correctly handles access to own data and the situation that visibilityStore and
+     * visibilityChecker are not configured.
+     *
+     * @param callerAccess      Visibility access info of the calling app
+     * @param targetPackageName The package name of the app that owns the data.
+     * @param prefixedSchema    The prefixed schema type the caller wants to access.
+     * @param visibilityStore   Store for visibility information. If not provided, only
+     *                          access to own data will be allowed.
+     * @param visibilityChecker Checker for visibility access. If not provided, only access to
+     *                          own data will be allowed.
+     * @return Whether access by the caller to this prefixed schema should be allowed.
+     */
+    public static boolean isSchemaSearchableByCaller(
+            @NonNull CallerAccess callerAccess,
+            @NonNull String targetPackageName,
+            @NonNull String prefixedSchema,
+            @Nullable VisibilityStore visibilityStore,
+            @Nullable VisibilityChecker visibilityChecker) {
+        Preconditions.checkNotNull(callerAccess);
+        Preconditions.checkNotNull(targetPackageName);
+        Preconditions.checkNotNull(prefixedSchema);
+
+        if (callerAccess.getCallingPackageName().equals(targetPackageName)) {
+            return true;  // Everyone is always allowed to retrieve their own data.
+        }
+        if (visibilityStore == null || visibilityChecker == null) {
+            return false;  // No visibility is configured at this time; no other access possible.
+        }
+        return visibilityChecker.isSchemaSearchableByCaller(
+                callerAccess,
+                targetPackageName,
+                prefixedSchema,
+                visibilityStore);
+    }
+}
diff --git a/appsearch/appsearch-platform-storage/api/current.txt b/appsearch/appsearch-platform-storage/api/current.txt
index 881789d..0b3b2e6 100644
--- a/appsearch/appsearch-platform-storage/api/current.txt
+++ b/appsearch/appsearch-platform-storage/api/current.txt
@@ -2,8 +2,10 @@
 package androidx.appsearch.platformstorage {
 
   @RequiresApi(android.os.Build.VERSION_CODES.S) public final class PlatformStorage {
-    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GlobalSearchSession!> createGlobalSearchSession(androidx.appsearch.platformstorage.PlatformStorage.GlobalSearchContext);
-    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSession(androidx.appsearch.platformstorage.PlatformStorage.SearchContext);
+    method @Deprecated public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GlobalSearchSession!> createGlobalSearchSession(androidx.appsearch.platformstorage.PlatformStorage.GlobalSearchContext);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GlobalSearchSession!> createGlobalSearchSessionAsync(androidx.appsearch.platformstorage.PlatformStorage.GlobalSearchContext);
+    method @Deprecated public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSession(androidx.appsearch.platformstorage.PlatformStorage.SearchContext);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSessionAsync(androidx.appsearch.platformstorage.PlatformStorage.SearchContext);
   }
 
   public static final class PlatformStorage.GlobalSearchContext {
diff --git a/appsearch/appsearch-platform-storage/api/public_plus_experimental_current.txt b/appsearch/appsearch-platform-storage/api/public_plus_experimental_current.txt
index 881789d..0b3b2e6 100644
--- a/appsearch/appsearch-platform-storage/api/public_plus_experimental_current.txt
+++ b/appsearch/appsearch-platform-storage/api/public_plus_experimental_current.txt
@@ -2,8 +2,10 @@
 package androidx.appsearch.platformstorage {
 
   @RequiresApi(android.os.Build.VERSION_CODES.S) public final class PlatformStorage {
-    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GlobalSearchSession!> createGlobalSearchSession(androidx.appsearch.platformstorage.PlatformStorage.GlobalSearchContext);
-    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSession(androidx.appsearch.platformstorage.PlatformStorage.SearchContext);
+    method @Deprecated public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GlobalSearchSession!> createGlobalSearchSession(androidx.appsearch.platformstorage.PlatformStorage.GlobalSearchContext);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GlobalSearchSession!> createGlobalSearchSessionAsync(androidx.appsearch.platformstorage.PlatformStorage.GlobalSearchContext);
+    method @Deprecated public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSession(androidx.appsearch.platformstorage.PlatformStorage.SearchContext);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSessionAsync(androidx.appsearch.platformstorage.PlatformStorage.SearchContext);
   }
 
   public static final class PlatformStorage.GlobalSearchContext {
diff --git a/appsearch/appsearch-platform-storage/api/restricted_current.txt b/appsearch/appsearch-platform-storage/api/restricted_current.txt
index 881789d..0b3b2e6 100644
--- a/appsearch/appsearch-platform-storage/api/restricted_current.txt
+++ b/appsearch/appsearch-platform-storage/api/restricted_current.txt
@@ -2,8 +2,10 @@
 package androidx.appsearch.platformstorage {
 
   @RequiresApi(android.os.Build.VERSION_CODES.S) public final class PlatformStorage {
-    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GlobalSearchSession!> createGlobalSearchSession(androidx.appsearch.platformstorage.PlatformStorage.GlobalSearchContext);
-    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSession(androidx.appsearch.platformstorage.PlatformStorage.SearchContext);
+    method @Deprecated public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GlobalSearchSession!> createGlobalSearchSession(androidx.appsearch.platformstorage.PlatformStorage.GlobalSearchContext);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GlobalSearchSession!> createGlobalSearchSessionAsync(androidx.appsearch.platformstorage.PlatformStorage.GlobalSearchContext);
+    method @Deprecated public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSession(androidx.appsearch.platformstorage.PlatformStorage.SearchContext);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSessionAsync(androidx.appsearch.platformstorage.PlatformStorage.SearchContext);
   }
 
   public static final class PlatformStorage.GlobalSearchContext {
diff --git a/appsearch/appsearch-platform-storage/build.gradle b/appsearch/appsearch-platform-storage/build.gradle
index 73bb4b7..e4c1f37 100644
--- a/appsearch/appsearch-platform-storage/build.gradle
+++ b/appsearch/appsearch-platform-storage/build.gradle
@@ -25,8 +25,9 @@
     api("androidx.annotation:annotation:1.1.0")
 
     implementation project(":appsearch:appsearch")
+    implementation('androidx.collection:collection:1.2.0')
     implementation("androidx.concurrent:concurrent-futures:1.0.0")
-    implementation("androidx.core:core:1.2.0")
+    implementation("androidx.core:core:1.7.0")
 
     androidTestImplementation(libs.testCore)
     androidTestImplementation(libs.testRules)
diff --git a/appsearch/appsearch-platform-storage/src/androidTest/java/androidx/appsearch/platformstorage/converter/AppSearchResultToPlatformConverterTest.java b/appsearch/appsearch-platform-storage/src/androidTest/java/androidx/appsearch/platformstorage/converter/AppSearchResultToPlatformConverterTest.java
new file mode 100644
index 0000000..3ee507c
--- /dev/null
+++ b/appsearch/appsearch-platform-storage/src/androidTest/java/androidx/appsearch/platformstorage/converter/AppSearchResultToPlatformConverterTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2022 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.appsearch.platformstorage.converter;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.os.Build;
+
+import androidx.appsearch.app.AppSearchResult;
+import androidx.concurrent.futures.ResolvableFuture;
+import androidx.test.filters.SdkSuppress;
+
+import org.junit.Test;
+
+import java.util.concurrent.ExecutionException;
+
+public class AppSearchResultToPlatformConverterTest {
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    public void testPlatformAppSearchResultToJetpack_catchException() {
+        android.app.appsearch.AppSearchResult<String> platformResult =
+                android.app.appsearch.AppSearchResult.newSuccessfulResult("42");
+        AppSearchResult<Integer> jetpackResult =
+                AppSearchResultToPlatformConverter.platformAppSearchResultToJetpack(
+                        platformResult,
+                        platformValue -> {
+                            throw new IllegalArgumentException("Test exception");
+                        }
+                );
+        assertThat(jetpackResult.getResultCode())
+                .isEqualTo(AppSearchResult.RESULT_INVALID_ARGUMENT);
+        assertThat(jetpackResult.getErrorMessage()).contains("Test exception");
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    public void testPlatformAppSearchResultToFuture_catchException() {
+        android.app.appsearch.AppSearchResult<String> platformResult =
+                android.app.appsearch.AppSearchResult.newSuccessfulResult("42");
+        ResolvableFuture<Integer> future = ResolvableFuture.create();
+        AppSearchResultToPlatformConverter.platformAppSearchResultToFuture(
+                platformResult,
+                future,
+                platformValue -> {
+                    throw new IllegalArgumentException("Test exception");
+                }
+        );
+        ExecutionException e = assertThrows(ExecutionException.class, future::get);
+        assertThat(e).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
+        assertThat(e).hasCauseThat().hasMessageThat().contains("Test exception");
+    }
+}
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/FeaturesImpl.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/FeaturesImpl.java
index 34ab614..5277649 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/FeaturesImpl.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/FeaturesImpl.java
@@ -15,6 +15,8 @@
  */
 package androidx.appsearch.platformstorage;
 
+import android.os.Build;
+
 import androidx.annotation.NonNull;
 import androidx.appsearch.app.Features;
 
@@ -27,14 +29,19 @@
     @Override
     public boolean isFeatureSupported(@NonNull String feature) {
         if (Features.SEARCH_RESULT_MATCH_INFO_SUBMATCH.equals(feature)) {
-            // TODO(b/201316758) : Update to reflect support in Android T+ once this feature is
-            // synced over into service-appsearch.
-            return false;
+            return Build.VERSION.SDK_INT >= 33;
         }
-        if (Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER.equals(feature)) {
-            // TODO(b/201316758) : Update to reflect support in Android T+ once this feature is
-            // synced over into service-appsearch.
-            return false;
+        if (Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK.equals(feature)) {
+            return Build.VERSION.SDK_INT >= 33;
+        }
+        if (Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA.equals(feature)) {
+            return Build.VERSION.SDK_INT >= 33;
+        }
+        if (Features.GLOBAL_SEARCH_SESSION_GET_BY_ID.equals(feature)) {
+            return Build.VERSION.SDK_INT >= 33;
+        }
+        if (Features.ADD_PERMISSIONS_AND_GET_VISIBILITY.equals(feature)) {
+            return Build.VERSION.SDK_INT >= 33;
         }
         return false;
     }
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/GlobalSearchSessionImpl.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/GlobalSearchSessionImpl.java
index 0984e13..33f6920 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/GlobalSearchSessionImpl.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/GlobalSearchSessionImpl.java
@@ -17,29 +17,44 @@
 
 import android.os.Build;
 
+import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.AppSearchBatchResult;
 import androidx.appsearch.app.Features;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.GetByDocumentIdRequest;
+import androidx.appsearch.app.GetSchemaResponse;
 import androidx.appsearch.app.GlobalSearchSession;
 import androidx.appsearch.app.ReportSystemUsageRequest;
 import androidx.appsearch.app.SearchResults;
 import androidx.appsearch.app.SearchSpec;
-import androidx.appsearch.observer.AppSearchObserverCallback;
+import androidx.appsearch.exceptions.AppSearchException;
+import androidx.appsearch.observer.DocumentChangeInfo;
+import androidx.appsearch.observer.ObserverCallback;
 import androidx.appsearch.observer.ObserverSpec;
+import androidx.appsearch.observer.SchemaChangeInfo;
 import androidx.appsearch.platformstorage.converter.AppSearchResultToPlatformConverter;
+import androidx.appsearch.platformstorage.converter.GenericDocumentToPlatformConverter;
+import androidx.appsearch.platformstorage.converter.GetSchemaResponseToPlatformConverter;
+import androidx.appsearch.platformstorage.converter.ObserverSpecToPlatformConverter;
 import androidx.appsearch.platformstorage.converter.RequestToPlatformConverter;
 import androidx.appsearch.platformstorage.converter.SearchSpecToPlatformConverter;
+import androidx.appsearch.platformstorage.util.BatchResultCallbackAdapter;
+import androidx.collection.ArrayMap;
 import androidx.concurrent.futures.ResolvableFuture;
 import androidx.core.util.Preconditions;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
+import java.util.Map;
 import java.util.concurrent.Executor;
 
 /**
  * An implementation of {@link androidx.appsearch.app.GlobalSearchSession} which proxies to a
  * platform {@link android.app.appsearch.GlobalSearchSession}.
+ *
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -49,6 +64,11 @@
     private final Executor mExecutor;
     private final Features mFeatures;
 
+    // Management of observer callbacks.
+    @GuardedBy("mObserverCallbacksLocked")
+    private final Map<ObserverCallback, android.app.appsearch.observer.ObserverCallback>
+            mObserverCallbacksLocked = new ArrayMap<>();
+
     GlobalSearchSessionImpl(
             @NonNull android.app.appsearch.GlobalSearchSession platformSession,
             @NonNull Executor executor,
@@ -58,6 +78,29 @@
         mFeatures = Preconditions.checkNotNull(features);
     }
 
+    @NonNull
+    @Override
+    public ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentIdAsync(
+            @NonNull String packageName, @NonNull String databaseName,
+            @NonNull GetByDocumentIdRequest request) {
+        if (Build.VERSION.SDK_INT < 33) {
+            throw new UnsupportedOperationException(Features.GLOBAL_SEARCH_SESSION_GET_BY_ID
+                    + " is not supported on this AppSearch implementation.");
+        } else {
+            Preconditions.checkNotNull(packageName);
+            Preconditions.checkNotNull(databaseName);
+            Preconditions.checkNotNull(request);
+            ResolvableFuture<AppSearchBatchResult<String, GenericDocument>> future =
+                    ResolvableFuture.create();
+            mPlatformSession.getByDocumentId(packageName, databaseName,
+                    RequestToPlatformConverter.toPlatformGetByDocumentIdRequest(request),
+                    mExecutor,
+                    new BatchResultCallbackAdapter<>(
+                            future, GenericDocumentToPlatformConverter::toJetpackGenericDocument));
+            return future;
+        }
+    }
+
     @Override
     @NonNull
     public SearchResults search(
@@ -74,7 +117,8 @@
 
     @NonNull
     @Override
-    public ListenableFuture<Void> reportSystemUsage(@NonNull ReportSystemUsageRequest request) {
+    public ListenableFuture<Void> reportSystemUsageAsync(
+            @NonNull ReportSystemUsageRequest request) {
         Preconditions.checkNotNull(request);
         ResolvableFuture<Void> future = ResolvableFuture.create();
         mPlatformSession.reportSystemUsage(
@@ -87,32 +131,132 @@
 
     @NonNull
     @Override
+    public ListenableFuture<GetSchemaResponse> getSchemaAsync(@NonNull String packageName,
+            @NonNull String databaseName) {
+        // Superclass is annotated with @RequiresFeature, so we shouldn't get here on an
+        // unsupported build.
+        if (Build.VERSION.SDK_INT < 33) {
+            throw new UnsupportedOperationException(
+                    Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA
+                            + " is not supported on this AppSearch implementation.");
+        } else {
+            ResolvableFuture<GetSchemaResponse> future = ResolvableFuture.create();
+            mPlatformSession.getSchema(
+                    packageName,
+                    databaseName,
+                    mExecutor,
+                    result -> AppSearchResultToPlatformConverter.platformAppSearchResultToFuture(
+                            result,
+                            future,
+                            GetSchemaResponseToPlatformConverter::toJetpackGetSchemaResponse));
+            return future;
+        }
+    }
+
+    @NonNull
+    @Override
     public Features getFeatures() {
         return mFeatures;
     }
 
     @Override
-    public void addObserver(
-            @NonNull String observedPackage,
+    public void registerObserverCallback(
+            @NonNull String targetPackageName,
             @NonNull ObserverSpec spec,
             @NonNull Executor executor,
-            @NonNull AppSearchObserverCallback observer) {
-        Preconditions.checkNotNull(observedPackage);
+            @NonNull ObserverCallback observer) throws AppSearchException {
+        Preconditions.checkNotNull(targetPackageName);
         Preconditions.checkNotNull(spec);
         Preconditions.checkNotNull(executor);
         Preconditions.checkNotNull(observer);
-        // TODO(b/193494000): Support change notifications in the platform backend once the
-        //  feature is exposed in the Android SDK.
-        throw new UnsupportedOperationException("addObserver not supported for platform yet");
+        // Superclass is annotated with @RequiresFeature, so we shouldn't get here on an
+        // unsupported build.
+        if (Build.VERSION.SDK_INT < 33) {
+            throw new UnsupportedOperationException(
+                    Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK
+                            + " is not supported on this AppSearch implementation");
+        } else {
+            synchronized (mObserverCallbacksLocked) {
+                android.app.appsearch.observer.ObserverCallback frameworkCallback =
+                        mObserverCallbacksLocked.get(observer);
+                if (frameworkCallback == null) {
+                    // No stub is associated with this package and observer, so we must create one.
+                    frameworkCallback = new android.app.appsearch.observer.ObserverCallback() {
+                        @Override
+                        public void onSchemaChanged(
+                                @NonNull android.app.appsearch.observer.SchemaChangeInfo
+                                        platformSchemaChangeInfo) {
+                            SchemaChangeInfo jetpackSchemaChangeInfo =
+                                    ObserverSpecToPlatformConverter.toJetpackSchemaChangeInfo(
+                                            platformSchemaChangeInfo);
+                            observer.onSchemaChanged(jetpackSchemaChangeInfo);
+                        }
+
+                        @Override
+                        public void onDocumentChanged(
+                                @NonNull android.app.appsearch.observer.DocumentChangeInfo
+                                        platformDocumentChangeInfo) {
+                            DocumentChangeInfo jetpackDocumentChangeInfo =
+                                    ObserverSpecToPlatformConverter.toJetpackDocumentChangeInfo(
+                                            platformDocumentChangeInfo);
+                            observer.onDocumentChanged(jetpackDocumentChangeInfo);
+                        }
+                    };
+                }
+
+                // Regardless of whether this stub was fresh or not, we have to register it again
+                // because the user might be supplying a different spec.
+                try {
+                    mPlatformSession.registerObserverCallback(
+                            targetPackageName,
+                            ObserverSpecToPlatformConverter.toPlatformObserverSpec(spec),
+                            executor,
+                            frameworkCallback);
+                } catch (android.app.appsearch.exceptions.AppSearchException e) {
+                    throw new AppSearchException((int) e.getResultCode(), e.getMessage(),
+                            e.getCause());
+                }
+
+                // Now that registration has succeeded, save this stub into our in-memory cache.
+                // This isn't done when errors occur because the user may not call removeObserver if
+                // addObserver threw.
+                mObserverCallbacksLocked.put(observer, frameworkCallback);
+            }
+        }
     }
 
     @Override
-    public void removeObserver(
-            @NonNull String observedPackage, @NonNull AppSearchObserverCallback observer) {
-        Preconditions.checkNotNull(observedPackage);
+    public void unregisterObserverCallback(
+            @NonNull String targetPackageName, @NonNull ObserverCallback observer)
+            throws AppSearchException {
+        Preconditions.checkNotNull(targetPackageName);
         Preconditions.checkNotNull(observer);
-        // TODO(b/193494000): Implement removeObserver
-        throw new UnsupportedOperationException("removeObserver not supported for platform yet");
+        // Superclass is annotated with @RequiresFeature, so we shouldn't get here on an
+        // unsupported build.
+        if (Build.VERSION.SDK_INT < 33) {
+            throw new UnsupportedOperationException(
+                    Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK
+                            + " is not supported on this AppSearch implementation");
+        } else {
+            android.app.appsearch.observer.ObserverCallback frameworkCallback;
+            synchronized (mObserverCallbacksLocked) {
+                frameworkCallback = mObserverCallbacksLocked.get(observer);
+                if (frameworkCallback == null) {
+                    return;  // No such observer registered. Nothing to do.
+                }
+
+                try {
+                    mPlatformSession.unregisterObserverCallback(targetPackageName,
+                            frameworkCallback);
+                } catch (android.app.appsearch.exceptions.AppSearchException e) {
+                    throw new AppSearchException((int) e.getResultCode(), e.getMessage(),
+                            e.getCause());
+                }
+
+                // Only remove from the in-memory map once removal from the service side succeeds
+                mObserverCallbacksLocked.remove(observer);
+            }
+        }
     }
 
     @Override
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/PlatformStorage.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/PlatformStorage.java
index ad345db..f7d8c23 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/PlatformStorage.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/PlatformStorage.java
@@ -209,7 +209,7 @@
      *                {@link AppSearchSession}
      */
     @NonNull
-    public static ListenableFuture<AppSearchSession> createSearchSession(
+    public static ListenableFuture<AppSearchSession> createSearchSessionAsync(
             @NonNull SearchContext context) {
         Preconditions.checkNotNull(context);
         AppSearchManager appSearchManager =
@@ -222,7 +222,7 @@
                     if (result.isSuccess()) {
                         future.set(
                                 new SearchSessionImpl(result.getResultValue(), context.mExecutor,
-                                new FeaturesImpl()));
+                                        new FeaturesImpl()));
                     } else {
                         future.setException(
                                 new AppSearchException(
@@ -233,10 +233,23 @@
     }
 
     /**
+     * @deprecated use {@link #createSearchSessionAsync}.
+     *
+     * @param context The {@link SearchContext} contains all information to create a new
+     *                {@link AppSearchSession}
+     */
+    @NonNull
+    @Deprecated
+    public static ListenableFuture<AppSearchSession> createSearchSession(
+            @NonNull SearchContext context) {
+        return createSearchSessionAsync(context);
+    }
+
+    /**
      * Opens a new {@link GlobalSearchSession} on this storage.
      */
     @NonNull
-    public static ListenableFuture<GlobalSearchSession> createGlobalSearchSession(
+    public static ListenableFuture<GlobalSearchSession> createGlobalSearchSessionAsync(
             @NonNull GlobalSearchContext context) {
         Preconditions.checkNotNull(context);
         AppSearchManager appSearchManager =
@@ -257,4 +270,14 @@
                 });
         return future;
     }
+
+    /**
+     * @deprecated use {@link #createGlobalSearchSessionAsync}.
+     */
+    @Deprecated
+    @NonNull
+    public static ListenableFuture<GlobalSearchSession> createGlobalSearchSession(
+            @NonNull GlobalSearchContext context) {
+        return createGlobalSearchSessionAsync(context);
+    }
 }
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchResultsImpl.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchResultsImpl.java
index f7390c8..3f5e679 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchResultsImpl.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchResultsImpl.java
@@ -58,23 +58,27 @@
 
     @Override
     @NonNull
-    public ListenableFuture<List<SearchResult>> getNextPage() {
+    public ListenableFuture<List<SearchResult>> getNextPageAsync() {
         ResolvableFuture<List<SearchResult>> future = ResolvableFuture.create();
         mPlatformResults.getNextPage(mExecutor, result -> {
             if (result.isSuccess()) {
                 List<android.app.appsearch.SearchResult> frameworkResults = result.getResultValue();
                 List<SearchResult> jetpackResults = new ArrayList<>(frameworkResults.size());
                 for (int i = 0; i < frameworkResults.size(); i++) {
-                    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.S) {
+                    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.S
+                            || Build.VERSION.SDK_INT == Build.VERSION_CODES.S_V2) {
                         // This is a patch for b/197361770, framework-appsearch in Android S will
                         // disable the whole namespace filter if none of given namespaces exist.
-                        // And that will result in Icing return all documents this query is able
-                        // to access.
+                        // And that will result in Icing returns all documents that this query is
+                        // able to access.
                         if (i == 0 && !mSearchSpec.getFilterNamespaces().isEmpty()
                                 && !mSearchSpec.getFilterNamespaces().contains(
                                 frameworkResults.get(i).getGenericDocument().getNamespace())) {
-                            // And in the meantime, since none of the namespace and document that
-                            // use query for exists, we should just return an empty result.
+                            // We should never return a document with a namespace that is not
+                            // required in the request. And also since the bug will only happen
+                            // when the required namespace doesn't exist, we should just return
+                            // an empty result when we found the result contains unexpected
+                            // namespace.
                             future.set(Collections.emptyList());
                             return;
                         }
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchSessionImpl.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchSessionImpl.java
index 4d8f2f2..41491322 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchSessionImpl.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchSessionImpl.java
@@ -37,9 +37,9 @@
 import androidx.appsearch.exceptions.AppSearchException;
 import androidx.appsearch.platformstorage.converter.AppSearchResultToPlatformConverter;
 import androidx.appsearch.platformstorage.converter.GenericDocumentToPlatformConverter;
+import androidx.appsearch.platformstorage.converter.GetSchemaResponseToPlatformConverter;
 import androidx.appsearch.platformstorage.converter.RequestToPlatformConverter;
 import androidx.appsearch.platformstorage.converter.ResponseToPlatformConverter;
-import androidx.appsearch.platformstorage.converter.SchemaToPlatformConverter;
 import androidx.appsearch.platformstorage.converter.SearchSpecToPlatformConverter;
 import androidx.appsearch.platformstorage.converter.SetSchemaRequestToPlatformConverter;
 import androidx.appsearch.platformstorage.util.BatchResultCallbackAdapter;
@@ -75,71 +75,47 @@
 
     @Override
     @NonNull
-    public ListenableFuture<SetSchemaResponse> setSchema(@NonNull SetSchemaRequest request) {
+    public ListenableFuture<SetSchemaResponse> setSchemaAsync(@NonNull SetSchemaRequest request) {
         Preconditions.checkNotNull(request);
         ResolvableFuture<SetSchemaResponse> future = ResolvableFuture.create();
         mPlatformSession.setSchema(
                 SetSchemaRequestToPlatformConverter.toPlatformSetSchemaRequest(request),
                 mExecutor,
                 mExecutor,
-                result -> {
-                    if (result.isSuccess()) {
-                        SetSchemaResponse jetpackResponse =
-                                SetSchemaRequestToPlatformConverter.toJetpackSetSchemaResponse(
-                                        result.getResultValue());
-                        future.set(jetpackResponse);
-                    } else {
-                        handleFailedPlatformResult(result, future);
-                    }
-                });
+                result -> AppSearchResultToPlatformConverter.platformAppSearchResultToFuture(
+                        result,
+                        future,
+                        SetSchemaRequestToPlatformConverter::toJetpackSetSchemaResponse));
         return future;
     }
 
     @Override
     @NonNull
-    public ListenableFuture<GetSchemaResponse> getSchema() {
+    public ListenableFuture<GetSchemaResponse> getSchemaAsync() {
         ResolvableFuture<GetSchemaResponse> future = ResolvableFuture.create();
         mPlatformSession.getSchema(
                 mExecutor,
-                result -> {
-                    if (result.isSuccess()) {
-                        android.app.appsearch.GetSchemaResponse platformGetResponse =
-                                result.getResultValue();
-                        GetSchemaResponse.Builder jetpackResponseBuilder =
-                                new GetSchemaResponse.Builder();
-                        for (android.app.appsearch.AppSearchSchema platformSchema :
-                                platformGetResponse.getSchemas()) {
-                            jetpackResponseBuilder.addSchema(
-                                    SchemaToPlatformConverter.toJetpackSchema(platformSchema));
-                        }
-                        jetpackResponseBuilder.setVersion(platformGetResponse.getVersion());
-                        future.set(jetpackResponseBuilder.build());
-                    } else {
-                        handleFailedPlatformResult(result, future);
-                    }
-                });
+                result -> AppSearchResultToPlatformConverter.platformAppSearchResultToFuture(
+                        result,
+                        future,
+                        GetSchemaResponseToPlatformConverter::toJetpackGetSchemaResponse));
         return future;
     }
 
     @NonNull
     @Override
-    public ListenableFuture<Set<String>> getNamespaces() {
+    public ListenableFuture<Set<String>> getNamespacesAsync() {
         ResolvableFuture<Set<String>> future = ResolvableFuture.create();
         mPlatformSession.getNamespaces(
                 mExecutor,
-                result -> {
-                    if (result.isSuccess()) {
-                        future.set(result.getResultValue());
-                    } else {
-                        handleFailedPlatformResult(result, future);
-                    }
-                });
+                result -> AppSearchResultToPlatformConverter.platformAppSearchResultToFuture(
+                        result, future));
         return future;
     }
 
     @Override
     @NonNull
-    public ListenableFuture<AppSearchBatchResult<String, Void>> put(
+    public ListenableFuture<AppSearchBatchResult<String, Void>> putAsync(
             @NonNull PutDocumentsRequest request) {
         Preconditions.checkNotNull(request);
         ResolvableFuture<AppSearchBatchResult<String, Void>> future = ResolvableFuture.create();
@@ -152,7 +128,7 @@
 
     @Override
     @NonNull
-    public ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentId(
+    public ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentIdAsync(
             @NonNull GetByDocumentIdRequest request) {
         Preconditions.checkNotNull(request);
         ResolvableFuture<AppSearchBatchResult<String, GenericDocument>> future =
@@ -181,7 +157,7 @@
 
     @Override
     @NonNull
-    public ListenableFuture<Void> reportUsage(@NonNull ReportUsageRequest request) {
+    public ListenableFuture<Void> reportUsageAsync(@NonNull ReportUsageRequest request) {
         Preconditions.checkNotNull(request);
         ResolvableFuture<Void> future = ResolvableFuture.create();
         mPlatformSession.reportUsage(
@@ -194,7 +170,7 @@
 
     @Override
     @NonNull
-    public ListenableFuture<AppSearchBatchResult<String, Void>> remove(
+    public ListenableFuture<AppSearchBatchResult<String, Void>> removeAsync(
             @NonNull RemoveByDocumentIdRequest request) {
         Preconditions.checkNotNull(request);
         ResolvableFuture<AppSearchBatchResult<String, Void>> future = ResolvableFuture.create();
@@ -207,14 +183,13 @@
 
     @Override
     @NonNull
-    public ListenableFuture<Void> remove(
+    public ListenableFuture<Void> removeAsync(
             @NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
         Preconditions.checkNotNull(queryExpression);
         Preconditions.checkNotNull(searchSpec);
         ResolvableFuture<Void> future = ResolvableFuture.create();
 
-        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.S
-                && !searchSpec.getFilterNamespaces().isEmpty()) {
+        if (Build.VERSION.SDK_INT < 33 && !searchSpec.getFilterNamespaces().isEmpty()) {
             // This is a patch for b/197361770, framework-appsearch in Android S will
             // disable the given namespace filter if it is not empty and none of given namespaces
             // exist.
@@ -223,7 +198,15 @@
             mPlatformSession.getNamespaces(
                     mExecutor,
                     namespaceResult -> {
-                        if (namespaceResult.isSuccess()) {
+                        if (!namespaceResult.isSuccess()) {
+                            future.setException(
+                                    new AppSearchException(
+                                            namespaceResult.getResultCode(),
+                                            namespaceResult.getErrorMessage()));
+                            return;
+                        }
+
+                        try {
                             Set<String> existingNamespaces = namespaceResult.getResultValue();
                             List<String> filterNamespaces = searchSpec.getFilterNamespaces();
                             for (int i = 0; i < filterNamespaces.size(); i++) {
@@ -234,17 +217,18 @@
                                             SearchSpecToPlatformConverter
                                                     .toPlatformSearchSpec(searchSpec),
                                             mExecutor,
-                                            removeResult -> AppSearchResultToPlatformConverter
-                                                    .platformAppSearchResultToFuture(removeResult,
-                                                            future));
+                                            removeResult ->
+                                                    AppSearchResultToPlatformConverter
+                                                            .platformAppSearchResultToFuture(
+                                                                    removeResult, future));
                                     return;
                                 }
                             }
                             // None of the namespace in the given namespace filter exists. Return
                             // early.
                             future.set(null);
-                        } else {
-                            handleFailedPlatformResult(namespaceResult, future);
+                        } catch (Throwable t) {
+                            future.setException(t);
                         }
                     });
         } else {
@@ -261,26 +245,19 @@
 
     @Override
     @NonNull
-    public ListenableFuture<StorageInfo> getStorageInfo() {
+    public ListenableFuture<StorageInfo> getStorageInfoAsync() {
         ResolvableFuture<StorageInfo> future = ResolvableFuture.create();
         mPlatformSession.getStorageInfo(
                 mExecutor,
-                result -> {
-                    if (result.isSuccess()) {
-                        StorageInfo jetpackStorageInfo =
-                                ResponseToPlatformConverter.toJetpackStorageInfo(
-                                        result.getResultValue());
-                        future.set(jetpackStorageInfo);
-                    } else {
-                        handleFailedPlatformResult(result, future);
-                    }
-                });
+                result -> AppSearchResultToPlatformConverter.platformAppSearchResultToFuture(
+                        result, future, ResponseToPlatformConverter::toJetpackStorageInfo)
+        );
         return future;
     }
 
     @NonNull
     @Override
-    public ListenableFuture<Void> requestFlush() {
+    public ListenableFuture<Void> requestFlushAsync() {
         ResolvableFuture<Void> future = ResolvableFuture.create();
         // The data in platform will be flushed by scheduled task. This api won't do anything extra
         // flush.
@@ -298,12 +275,4 @@
     public void close() {
         mPlatformSession.close();
     }
-
-    private void handleFailedPlatformResult(
-            @NonNull android.app.appsearch.AppSearchResult<?> platformResult,
-            @NonNull ResolvableFuture<?> future) {
-        future.setException(
-                new AppSearchException(
-                        platformResult.getResultCode(), platformResult.getErrorMessage()));
-    }
 }
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/AppSearchResultToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/AppSearchResultToPlatformConverter.java
index 1510626..6d9a999 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/AppSearchResultToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/AppSearchResultToPlatformConverter.java
@@ -45,11 +45,18 @@
      * {@link androidx.appsearch.app.AppSearchResult}.
      */
     @NonNull
-    public static <T> AppSearchResult<T> platformAppSearchResultToJetpack(
-            @NonNull android.app.appsearch.AppSearchResult<T> platformResult) {
+    public static <PlatformType, JetpackType> AppSearchResult<JetpackType>
+            platformAppSearchResultToJetpack(
+            @NonNull android.app.appsearch.AppSearchResult<PlatformType> platformResult,
+            @NonNull Function<PlatformType, JetpackType> valueMapper) {
         Preconditions.checkNotNull(platformResult);
         if (platformResult.isSuccess()) {
-            return AppSearchResult.newSuccessfulResult(platformResult.getResultValue());
+            try {
+                JetpackType jetpackType = valueMapper.apply(platformResult.getResultValue());
+                return AppSearchResult.newSuccessfulResult(jetpackType);
+            } catch (Throwable t) {
+                return AppSearchResult.throwableToFailedResult(t);
+            }
         }
         return AppSearchResult.newFailedResult(
                 platformResult.getResultCode(), platformResult.getErrorMessage());
@@ -57,20 +64,36 @@
 
     /**
      * Uses the given {@link android.app.appsearch.AppSearchResult} to populate the given
+     * {@link ResolvableFuture}, transforming it using {@code valueMapper}.
+     */
+    public static <PlatformType, JetpackType> void platformAppSearchResultToFuture(
+            @NonNull android.app.appsearch.AppSearchResult<PlatformType> platformResult,
+            @NonNull ResolvableFuture<JetpackType> future,
+            @NonNull Function<PlatformType, JetpackType> valueMapper) {
+        Preconditions.checkNotNull(platformResult);
+        Preconditions.checkNotNull(future);
+        if (platformResult.isSuccess()) {
+            try {
+                JetpackType jetpackType = valueMapper.apply(platformResult.getResultValue());
+                future.set(jetpackType);
+            } catch (Throwable t) {
+                future.setException(t);
+            }
+        } else {
+            future.setException(
+                    new AppSearchException(
+                            platformResult.getResultCode(), platformResult.getErrorMessage()));
+        }
+    }
+
+    /**
+     * Uses the given {@link android.app.appsearch.AppSearchResult} to populate the given
      * {@link ResolvableFuture}.
      */
     public static <T> void platformAppSearchResultToFuture(
             @NonNull android.app.appsearch.AppSearchResult<T> platformResult,
             @NonNull ResolvableFuture<T> future) {
-        Preconditions.checkNotNull(platformResult);
-        Preconditions.checkNotNull(future);
-        if (platformResult.isSuccess()) {
-            future.set(platformResult.getResultValue());
-        } else {
-            future.setException(
-                    new AppSearchException(
-                            platformResult.getResultCode(), platformResult.getErrorMessage()));
-        }
+        platformAppSearchResultToFuture(platformResult, future, Function.identity());
     }
 
     /**
@@ -89,8 +112,13 @@
         AppSearchBatchResult.Builder<K, JetpackValue> jetpackResult =
                 new AppSearchBatchResult.Builder<>();
         for (Map.Entry<K, PlatformValue> success : platformResult.getSuccesses().entrySet()) {
-            JetpackValue jetpackValue = valueMapper.apply(success.getValue());
-            jetpackResult.setSuccess(success.getKey(), jetpackValue);
+            try {
+                JetpackValue jetpackValue = valueMapper.apply(success.getValue());
+                jetpackResult.setSuccess(success.getKey(), jetpackValue);
+            } catch (Throwable t) {
+                jetpackResult.setResult(
+                        success.getKey(), AppSearchResult.throwableToFailedResult(t));
+            }
         }
         for (Map.Entry<K, android.app.appsearch.AppSearchResult<PlatformValue>> failure :
                 platformResult.getFailures().entrySet()) {
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GenericDocumentToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GenericDocumentToPlatformConverter.java
index 3838191..004fcc4 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GenericDocumentToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GenericDocumentToPlatformConverter.java
@@ -61,9 +61,24 @@
             } else if (property instanceof boolean[]) {
                 platformBuilder.setPropertyBoolean(propertyName, (boolean[]) property);
             } else if (property instanceof byte[][]) {
-                platformBuilder.setPropertyBytes(propertyName, (byte[][]) property);
+                byte[][] byteValues = (byte[][]) property;
+                // This is a patch for b/204677124, framework-appsearch in Android S and S_V2 will
+                // crash if the user put a document with empty byte[][] or document[].
+                if ((Build.VERSION.SDK_INT == Build.VERSION_CODES.S
+                        || Build.VERSION.SDK_INT == Build.VERSION_CODES.S_V2)
+                        && byteValues.length == 0) {
+                    continue;
+                }
+                platformBuilder.setPropertyBytes(propertyName, byteValues);
             } else if (property instanceof GenericDocument[]) {
                 GenericDocument[] documentValues = (GenericDocument[]) property;
+                // This is a patch for b/204677124, framework-appsearch in Android S and S_V2 will
+                // crash if the user put a document with empty byte[][] or document[].
+                if ((Build.VERSION.SDK_INT == Build.VERSION_CODES.S
+                        || Build.VERSION.SDK_INT == Build.VERSION_CODES.S_V2)
+                        && documentValues.length == 0) {
+                    continue;
+                }
                 android.app.appsearch.GenericDocument[] platformSubDocuments =
                         new android.app.appsearch.GenericDocument[documentValues.length];
                 for (int j = 0; j < documentValues.length; j++) {
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GetSchemaResponseToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GetSchemaResponseToPlatformConverter.java
new file mode 100644
index 0000000..920d237
--- /dev/null
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GetSchemaResponseToPlatformConverter.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2022 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.appsearch.platformstorage.converter;
+
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.GetSchemaResponse;
+import androidx.appsearch.app.PackageIdentifier;
+import androidx.collection.ArraySet;
+import androidx.core.util.Preconditions;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Translates between Platform and Jetpack versions of {@link GetSchemaResponse}.
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+@RequiresApi(Build.VERSION_CODES.S)
+public final class GetSchemaResponseToPlatformConverter {
+    private GetSchemaResponseToPlatformConverter() {}
+
+    /**
+     * Translates a platform {@link android.app.appsearch.GetSchemaResponse} into a jetpack
+     * {@link GetSchemaResponse}.
+     */
+    @NonNull
+    public static GetSchemaResponse toJetpackGetSchemaResponse(
+            @NonNull android.app.appsearch.GetSchemaResponse platformResponse) {
+        Preconditions.checkNotNull(platformResponse);
+        GetSchemaResponse.Builder jetpackBuilder;
+        if (Build.VERSION.SDK_INT < 33) {
+            // Android API level in S-v2 and lower won't have any supported feature.
+            jetpackBuilder = new GetSchemaResponse.Builder(/*getVisibilitySettingSupported=*/false);
+        } else {
+            // The regular builder has all supported features.
+            jetpackBuilder = new GetSchemaResponse.Builder();
+        }
+        for (android.app.appsearch.AppSearchSchema platformSchema : platformResponse.getSchemas()) {
+            jetpackBuilder.addSchema(SchemaToPlatformConverter.toJetpackSchema(platformSchema));
+        }
+        jetpackBuilder.setVersion(platformResponse.getVersion());
+        if (Build.VERSION.SDK_INT >= 33) {
+            // Convert schemas not displayed by system
+            for (String schemaTypeNotDisplayedBySystem :
+                    platformResponse.getSchemaTypesNotDisplayedBySystem()) {
+                jetpackBuilder.addSchemaTypeNotDisplayedBySystem(schemaTypeNotDisplayedBySystem);
+            }
+            // Convert schemas visible to packages
+            convertSchemasVisibleToPackages(platformResponse, jetpackBuilder);
+            // Convert schemas visible to permissions
+            for (Map.Entry<String, Set<Set<Integer>>> entry :
+                    platformResponse.getRequiredPermissionsForSchemaTypeVisibility().entrySet()) {
+                jetpackBuilder.setRequiredPermissionsForSchemaTypeVisibility(entry.getKey(),
+                        entry.getValue());
+            }
+        }
+        return jetpackBuilder.build();
+    }
+
+    /**
+     * Adds package visibilities in a platform {@link android.app.appsearch.GetSchemaResponse} into
+     * the given jetpack {@link GetSchemaResponse}.
+     */
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    private static void convertSchemasVisibleToPackages(
+            @NonNull android.app.appsearch.GetSchemaResponse platformResponse,
+            @NonNull GetSchemaResponse.Builder jetpackBuilder) {
+        // TODO(b/205749173): If there were no packages, getSchemaTypesVisibleToPackages
+        //  incorrectly returns {@code null} in some prerelease versions of Android T. Remove
+        //  this workaround after the issue is fixed in T.
+        Map<String, Set<android.app.appsearch.PackageIdentifier>> schemaTypesVisibleToPackages =
+                platformResponse.getSchemaTypesVisibleToPackages();
+        if (schemaTypesVisibleToPackages != null) {
+            for (Map.Entry<String, Set<android.app.appsearch.PackageIdentifier>> entry
+                    : schemaTypesVisibleToPackages.entrySet()) {
+                Set<PackageIdentifier> jetpackPackageIdentifiers =
+                        new ArraySet<>(entry.getValue().size());
+                for (android.app.appsearch.PackageIdentifier frameworkPackageIdentifier
+                        : entry.getValue()) {
+                    jetpackPackageIdentifiers.add(new PackageIdentifier(
+                            frameworkPackageIdentifier.getPackageName(),
+                            frameworkPackageIdentifier.getSha256Certificate()));
+                }
+                jetpackBuilder.setSchemaTypeVisibleToPackages(
+                        entry.getKey(), jetpackPackageIdentifiers);
+            }
+        }
+    }
+}
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/ObserverSpecToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/ObserverSpecToPlatformConverter.java
new file mode 100644
index 0000000..41ca827
--- /dev/null
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/ObserverSpecToPlatformConverter.java
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ * 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.appsearch.platformstorage.converter;
+
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.observer.DocumentChangeInfo;
+import androidx.appsearch.observer.ObserverSpec;
+import androidx.appsearch.observer.SchemaChangeInfo;
+import androidx.core.util.Preconditions;
+
+/**
+ * Translates between Platform and Jetpack versions of {@link ObserverSpec}.
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public final class ObserverSpecToPlatformConverter {
+    private ObserverSpecToPlatformConverter() {}
+
+    /**
+     * Translates a jetpack {@link ObserverSpec} into a platform
+     * {@link android.app.appsearch.observer.ObserverSpec}.
+     */
+    @NonNull
+    public static android.app.appsearch.observer.ObserverSpec toPlatformObserverSpec(
+            @NonNull ObserverSpec jetpackSpec) {
+        Preconditions.checkNotNull(jetpackSpec);
+        return new android.app.appsearch.observer.ObserverSpec.Builder()
+                .addFilterSchemas(jetpackSpec.getFilterSchemas())
+                .build();
+    }
+
+    /**
+     * Translates a platform {@link androidx.appsearch.observer.SchemaChangeInfo} into a jetpack
+     * {@link SchemaChangeInfo}.
+     */
+    @NonNull
+    public static SchemaChangeInfo toJetpackSchemaChangeInfo(
+            @NonNull android.app.appsearch.observer.SchemaChangeInfo platformInfo) {
+        Preconditions.checkNotNull(platformInfo);
+        return new SchemaChangeInfo(
+                platformInfo.getPackageName(),
+                platformInfo.getDatabaseName(),
+                platformInfo.getChangedSchemaNames());
+    }
+
+    /**
+     * Translates a platform {@link androidx.appsearch.observer.DocumentChangeInfo} into a jetpack
+     * {@link DocumentChangeInfo}.
+     */
+    @NonNull
+    public static DocumentChangeInfo toJetpackDocumentChangeInfo(
+            @NonNull android.app.appsearch.observer.DocumentChangeInfo platformInfo) {
+        Preconditions.checkNotNull(platformInfo);
+        return new DocumentChangeInfo(
+                platformInfo.getPackageName(),
+                platformInfo.getDatabaseName(),
+                platformInfo.getNamespace(),
+                platformInfo.getSchemaName(),
+                platformInfo.getChangedDocumentIds());
+    }
+}
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchResultToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchResultToPlatformConverter.java
index 841cbe7..0c978c2 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchResultToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchResultToPlatformConverter.java
@@ -60,9 +60,8 @@
     private static SearchResult.MatchInfo toJetpackMatchInfo(
             @NonNull android.app.appsearch.SearchResult.MatchInfo platformMatchInfo) {
         Preconditions.checkNotNull(platformMatchInfo);
-        // TODO(b/201316758) : Copy over submatch range info once it is added to
-        //  framework-appsearch.
-        return new SearchResult.MatchInfo.Builder(platformMatchInfo.getPropertyPath())
+        SearchResult.MatchInfo.Builder builder = new SearchResult.MatchInfo.Builder(
+                platformMatchInfo.getPropertyPath())
                 .setExactMatchRange(
                         new SearchResult.MatchRange(
                                 platformMatchInfo.getExactMatchRange().getStart(),
@@ -70,7 +69,13 @@
                 .setSnippetRange(
                         new SearchResult.MatchRange(
                                 platformMatchInfo.getSnippetRange().getStart(),
-                                platformMatchInfo.getSnippetRange().getEnd()))
-                .build();
+                                platformMatchInfo.getSnippetRange().getEnd()));
+        if (Build.VERSION.SDK_INT >= 33) {
+            builder.setSubmatchRange(
+                    new SearchResult.MatchRange(
+                            platformMatchInfo.getSubmatchRange().getStart(),
+                            platformMatchInfo.getSubmatchRange().getEnd()));
+        }
+        return builder.build();
     }
 }
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SetSchemaRequestToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SetSchemaRequestToPlatformConverter.java
index ca52112..b70381a 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SetSchemaRequestToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SetSchemaRequestToPlatformConverter.java
@@ -31,6 +31,7 @@
 
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Function;
 
 /**
  * Translates between Platform and Jetpack versions of {@link SetSchemaRequest}.
@@ -70,6 +71,20 @@
                                 jetpackPackageIdentifier.getSha256Certificate()));
             }
         }
+        if (!jetpackRequest.getRequiredPermissionsForSchemaTypeVisibility().isEmpty()) {
+            if (Build.VERSION.SDK_INT < 33) {
+                throw new UnsupportedOperationException(
+                        "Set required permissions for schema type visibility are not supported "
+                                + "with this backend/Android API level combination.");
+            }
+            for (Map.Entry<String, Set<Set<Integer>>> entry :
+                    jetpackRequest.getRequiredPermissionsForSchemaTypeVisibility().entrySet()) {
+                for (Set<Integer> permissionGroup : entry.getValue()) {
+                    platformBuilder.addRequiredPermissionsForSchemaTypeVisibility(
+                            entry.getKey(), permissionGroup);
+                }
+            }
+        }
         for (Map.Entry<String, Migrator> entry : jetpackRequest.getMigrators().entrySet()) {
             Migrator jetpackMigrator = entry.getValue();
             android.app.appsearch.Migrator platformMigrator = new android.app.appsearch.Migrator() {
@@ -141,7 +156,8 @@
                     migrationFailure.getDocumentId(),
                     migrationFailure.getSchemaType(),
                     AppSearchResultToPlatformConverter.platformAppSearchResultToJetpack(
-                            migrationFailure.getAppSearchResult())));
+                            migrationFailure.getAppSearchResult(), Function.identity()))
+            );
         }
         return jetpackBuilder.build();
     }
diff --git a/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/AppSearchTestUtils.java b/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/AppSearchTestUtils.java
index f578822..3c2943e 100644
--- a/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/AppSearchTestUtils.java
+++ b/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/AppSearchTestUtils.java
@@ -27,6 +27,7 @@
 import androidx.appsearch.app.GetByDocumentIdRequest;
 import androidx.appsearch.app.SearchResult;
 import androidx.appsearch.app.SearchResults;
+import androidx.appsearch.localstorage.visibilitystore.VisibilityChecker;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -59,7 +60,7 @@
             @NonNull AppSearchSession session, @NonNull String namespace, @NonNull String... ids)
             throws Exception {
         AppSearchBatchResult<String, GenericDocument> result = checkIsBatchResultSuccess(
-                session.getByDocumentId(
+                session.getByDocumentIdAsync(
                         new GetByDocumentIdRequest.Builder(namespace).addIds(ids).build()));
         assertThat(result.getSuccesses()).hasSize(ids.length);
         assertThat(result.getFailures()).isEmpty();
@@ -76,7 +77,7 @@
             @NonNull AppSearchSession session, @NonNull GetByDocumentIdRequest request)
             throws Exception {
         AppSearchBatchResult<String, GenericDocument> result = checkIsBatchResultSuccess(
-                session.getByDocumentId(request));
+                session.getByDocumentIdAsync(request));
         Set<String> ids = request.getIds();
         assertThat(result.getSuccesses()).hasSize(ids.size());
         assertThat(result.getFailures()).isEmpty();
@@ -104,12 +105,24 @@
     @NonNull
     public static List<SearchResult> retrieveAllSearchResults(@NonNull SearchResults searchResults)
             throws Exception {
-        List<SearchResult> page = searchResults.getNextPage().get();
+        List<SearchResult> page = searchResults.getNextPageAsync().get();
         List<SearchResult> results = new ArrayList<>();
         while (!page.isEmpty()) {
             results.addAll(page);
-            page = searchResults.getNextPage().get();
+            page = searchResults.getNextPageAsync().get();
         }
         return results;
     }
+
+    /**
+     * Creates a mock {@link VisibilityChecker}.
+     * @param visiblePrefixedSchemas Schema types that are accessible to any caller.
+     * @return
+     */
+    @NonNull
+    public static VisibilityChecker createMockVisibilityChecker(
+            @NonNull Set<String> visiblePrefixedSchemas) {
+        return (callerAccess, packageName, prefixedSchema, visibilityStore) ->
+                visiblePrefixedSchemas.contains(prefixedSchema);
+    }
 }
diff --git a/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/TestObserverCallback.java b/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/TestObserverCallback.java
index 93cb2ce..a22d02e 100644
--- a/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/TestObserverCallback.java
+++ b/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/TestObserverCallback.java
@@ -19,15 +19,15 @@
 import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
-import androidx.appsearch.observer.AppSearchObserverCallback;
 import androidx.appsearch.observer.DocumentChangeInfo;
+import androidx.appsearch.observer.ObserverCallback;
 import androidx.appsearch.observer.SchemaChangeInfo;
 
 import java.util.ArrayList;
 import java.util.List;
 
 /**
- * An implementation of {@link androidx.appsearch.observer.AppSearchObserverCallback} for testing
+ * An implementation of {@link androidx.appsearch.observer.ObserverCallback} for testing
  * that caches its notifications in memory.
  *
  * <p>You should wait for all notifications to be delivered using {@link #waitForNotificationCount}
@@ -36,7 +36,7 @@
  * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-public class TestObserverCallback implements AppSearchObserverCallback {
+public class TestObserverCallback implements ObserverCallback {
     private final Object mLock = new Object();
 
     private final List<SchemaChangeInfo> mSchemaChanges = new ArrayList<>();
@@ -81,7 +81,11 @@
                                     + expectedCount
                                     + " notifications but there are"
                                     + " already "
-                                    + actualCount);
+                                    + actualCount
+                                    + ".\n  Schema changes: "
+                                    + mSchemaChanges
+                                    + "\n  Document changes: "
+                                    + mDocumentChanges);
                 } else if (actualCount == expectedCount) {
                     return;
                 } else {
@@ -111,6 +115,16 @@
         return mDocumentChanges;
     }
 
+    /** Removes all notifications captured by this callback and resets the count to 0. */
+    public void clear() {
+        synchronized (mLock) {
+            mSchemaChanges.clear();
+            mDocumentChanges.clear();
+            mNotificationCountLocked = 0;
+            mLock.notifyAll();
+        }
+    }
+
     private void incrementNotificationCountLocked() {
         synchronized (mLock) {
             mNotificationCountLocked++;
diff --git a/appsearch/appsearch/api/api_lint.ignore b/appsearch/appsearch/api/api_lint.ignore
index 36bb389..aa14c59 100644
--- a/appsearch/appsearch/api/api_lint.ignore
+++ b/appsearch/appsearch/api/api_lint.ignore
@@ -19,6 +19,8 @@
     Methods returning com.google.common.util.concurrent.ListenableFuture should have a suffix *Async to reserve unmodified name for a suspend function
 AsyncSuffixFuture: androidx.appsearch.app.AppSearchSession#setSchema(androidx.appsearch.app.SetSchemaRequest):
     Methods returning com.google.common.util.concurrent.ListenableFuture should have a suffix *Async to reserve unmodified name for a suspend function
+AsyncSuffixFuture: androidx.appsearch.app.GlobalSearchSession#getSchema(String, String):
+    Methods returning com.google.common.util.concurrent.ListenableFuture should have a suffix *Async to reserve unmodified name for a suspend function
 AsyncSuffixFuture: androidx.appsearch.app.GlobalSearchSession#reportSystemUsage(androidx.appsearch.app.ReportSystemUsageRequest):
     Methods returning com.google.common.util.concurrent.ListenableFuture should have a suffix *Async to reserve unmodified name for a suspend function
 AsyncSuffixFuture: androidx.appsearch.app.SearchResults#getNextPage():
diff --git a/appsearch/appsearch/api/current.txt b/appsearch/appsearch/api/current.txt
index 91b14d5..0529d14 100644
--- a/appsearch/appsearch/api/current.txt
+++ b/appsearch/appsearch/api/current.txt
@@ -177,18 +177,28 @@
 
   public interface AppSearchSession extends java.io.Closeable {
     method public void close();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,androidx.appsearch.app.GenericDocument!>!> getByDocumentId(androidx.appsearch.app.GetByDocumentIdRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,androidx.appsearch.app.GenericDocument!>!> getByDocumentId(androidx.appsearch.app.GetByDocumentIdRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,androidx.appsearch.app.GenericDocument!>!> getByDocumentIdAsync(androidx.appsearch.app.GetByDocumentIdRequest);
     method public androidx.appsearch.app.Features getFeatures();
-    method public com.google.common.util.concurrent.ListenableFuture<java.util.Set<java.lang.String!>!> getNamespaces();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchema();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.StorageInfo!> getStorageInfo();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> put(androidx.appsearch.app.PutDocumentsRequest);
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> remove(androidx.appsearch.app.RemoveByDocumentIdRequest);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> remove(String, androidx.appsearch.app.SearchSpec);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportUsage(androidx.appsearch.app.ReportUsageRequest);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> requestFlush();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.util.Set<java.lang.String!>!> getNamespaces();
+    method public com.google.common.util.concurrent.ListenableFuture<java.util.Set<java.lang.String!>!> getNamespacesAsync();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchema();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchemaAsync();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.StorageInfo!> getStorageInfo();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.StorageInfo!> getStorageInfoAsync();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> put(androidx.appsearch.app.PutDocumentsRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> putAsync(androidx.appsearch.app.PutDocumentsRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> remove(androidx.appsearch.app.RemoveByDocumentIdRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> remove(String, androidx.appsearch.app.SearchSpec);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> removeAsync(androidx.appsearch.app.RemoveByDocumentIdRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> removeAsync(String, androidx.appsearch.app.SearchSpec);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportUsage(androidx.appsearch.app.ReportUsageRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportUsageAsync(androidx.appsearch.app.ReportUsageRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> requestFlush();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> requestFlushAsync();
     method public androidx.appsearch.app.SearchResults search(String, androidx.appsearch.app.SearchSpec);
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.SetSchemaResponse!> setSchema(androidx.appsearch.app.SetSchemaRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.SetSchemaResponse!> setSchema(androidx.appsearch.app.SetSchemaRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.SetSchemaResponse!> setSchemaAsync(androidx.appsearch.app.SetSchemaRequest);
   }
 
   public interface DocumentClassFactory<T> {
@@ -200,7 +210,10 @@
 
   public interface Features {
     method public boolean isFeatureSupported(String);
-    field public static final String GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER = "GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER";
+    field public static final String ADD_PERMISSIONS_AND_GET_VISIBILITY = "ADD_PERMISSIONS_AND_GET_VISIBILITY";
+    field public static final String GLOBAL_SEARCH_SESSION_GET_BY_ID = "GLOBAL_SEARCH_SESSION_GET_BY_ID";
+    field public static final String GLOBAL_SEARCH_SESSION_GET_SCHEMA = "GLOBAL_SEARCH_SESSION_GET_SCHEMA";
+    field public static final String GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK = "GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK";
     field public static final String SEARCH_RESULT_MATCH_INFO_SUBMATCH = "SEARCH_RESULT_MATCH_INFO_SUBMATCH";
   }
 
@@ -266,6 +279,9 @@
   }
 
   public final class GetSchemaResponse {
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public java.util.Map<java.lang.String!,java.util.Set<java.util.Set<java.lang.Integer!>!>!> getRequiredPermissionsForSchemaTypeVisibility();
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public java.util.Set<java.lang.String!> getSchemaTypesNotDisplayedBySystem();
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public java.util.Map<java.lang.String!,java.util.Set<androidx.appsearch.app.PackageIdentifier!>!> getSchemaTypesVisibleToPackages();
     method public java.util.Set<androidx.appsearch.app.AppSearchSchema!> getSchemas();
     method @IntRange(from=0) public int getVersion();
   }
@@ -273,17 +289,24 @@
   public static final class GetSchemaResponse.Builder {
     ctor public GetSchemaResponse.Builder();
     method public androidx.appsearch.app.GetSchemaResponse.Builder addSchema(androidx.appsearch.app.AppSearchSchema);
+    method public androidx.appsearch.app.GetSchemaResponse.Builder addSchemaTypeNotDisplayedBySystem(String);
     method public androidx.appsearch.app.GetSchemaResponse build();
+    method public androidx.appsearch.app.GetSchemaResponse.Builder setRequiredPermissionsForSchemaTypeVisibility(String, java.util.Set<java.util.Set<java.lang.Integer!>!>);
+    method public androidx.appsearch.app.GetSchemaResponse.Builder setSchemaTypeVisibleToPackages(String, java.util.Set<androidx.appsearch.app.PackageIdentifier!>);
     method public androidx.appsearch.app.GetSchemaResponse.Builder setVersion(@IntRange(from=0) int);
   }
 
   public interface GlobalSearchSession extends java.io.Closeable {
-    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER) public void addObserver(String, androidx.appsearch.observer.ObserverSpec, java.util.concurrent.Executor, androidx.appsearch.observer.AppSearchObserverCallback);
     method public void close();
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_GET_BY_ID) public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,androidx.appsearch.app.GenericDocument!>!> getByDocumentIdAsync(String, String, androidx.appsearch.app.GetByDocumentIdRequest);
     method public androidx.appsearch.app.Features getFeatures();
-    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER) public void removeObserver(String, androidx.appsearch.observer.AppSearchObserverCallback);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportSystemUsage(androidx.appsearch.app.ReportSystemUsageRequest);
+    method @Deprecated @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA) public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchema(String, String);
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA) public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchemaAsync(String, String);
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK) public void registerObserverCallback(String, androidx.appsearch.observer.ObserverSpec, java.util.concurrent.Executor, androidx.appsearch.observer.ObserverCallback) throws androidx.appsearch.exceptions.AppSearchException;
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportSystemUsage(androidx.appsearch.app.ReportSystemUsageRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportSystemUsageAsync(androidx.appsearch.app.ReportSystemUsageRequest);
     method public androidx.appsearch.app.SearchResults search(String, androidx.appsearch.app.SearchSpec);
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK) public void unregisterObserverCallback(String, androidx.appsearch.observer.ObserverCallback) throws androidx.appsearch.exceptions.AppSearchException;
   }
 
   public abstract class Migrator {
@@ -395,7 +418,8 @@
 
   public interface SearchResults extends java.io.Closeable {
     method public void close();
-    method public com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.appsearch.app.SearchResult!>!> getNextPage();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.appsearch.app.SearchResult!>!> getNextPage();
+    method public com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.appsearch.app.SearchResult!>!> getNextPageAsync();
   }
 
   public final class SearchSpec {
@@ -453,20 +477,31 @@
 
   public final class SetSchemaRequest {
     method public java.util.Map<java.lang.String!,androidx.appsearch.app.Migrator!> getMigrators();
+    method public java.util.Map<java.lang.String!,java.util.Set<java.util.Set<java.lang.Integer!>!>!> getRequiredPermissionsForSchemaTypeVisibility();
     method public java.util.Set<androidx.appsearch.app.AppSearchSchema!> getSchemas();
     method public java.util.Set<java.lang.String!> getSchemasNotDisplayedBySystem();
     method public java.util.Map<java.lang.String!,java.util.Set<androidx.appsearch.app.PackageIdentifier!>!> getSchemasVisibleToPackages();
     method @IntRange(from=1) public int getVersion();
     method public boolean isForceOverride();
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_ASSISTANT_APP_SEARCH_DATA = 6; // 0x6
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_CALENDAR = 2; // 0x2
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_CONTACTS = 3; // 0x3
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_EXTERNAL_STORAGE = 4; // 0x4
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_HOME_APP_SEARCH_DATA = 5; // 0x5
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_SMS = 1; // 0x1
   }
 
   public static final class SetSchemaRequest.Builder {
     ctor public SetSchemaRequest.Builder();
     method public androidx.appsearch.app.SetSchemaRequest.Builder addDocumentClasses(Class<?>!...) throws androidx.appsearch.exceptions.AppSearchException;
     method public androidx.appsearch.app.SetSchemaRequest.Builder addDocumentClasses(java.util.Collection<? extends java.lang.Class<?>>) throws androidx.appsearch.exceptions.AppSearchException;
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public androidx.appsearch.app.SetSchemaRequest.Builder addRequiredPermissionsForDocumentClassVisibility(Class<?>, java.util.Set<java.lang.Integer!>) throws androidx.appsearch.exceptions.AppSearchException;
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public androidx.appsearch.app.SetSchemaRequest.Builder addRequiredPermissionsForSchemaTypeVisibility(String, java.util.Set<java.lang.Integer!>);
     method public androidx.appsearch.app.SetSchemaRequest.Builder addSchemas(androidx.appsearch.app.AppSearchSchema!...);
     method public androidx.appsearch.app.SetSchemaRequest.Builder addSchemas(java.util.Collection<androidx.appsearch.app.AppSearchSchema!>);
     method public androidx.appsearch.app.SetSchemaRequest build();
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public androidx.appsearch.app.SetSchemaRequest.Builder clearRequiredPermissionsForDocumentClassVisibility(Class<?>) throws androidx.appsearch.exceptions.AppSearchException;
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public androidx.appsearch.app.SetSchemaRequest.Builder clearRequiredPermissionsForSchemaTypeVisibility(String);
     method public androidx.appsearch.app.SetSchemaRequest.Builder setDocumentClassDisplayedBySystem(Class<?>, boolean) throws androidx.appsearch.exceptions.AppSearchException;
     method public androidx.appsearch.app.SetSchemaRequest.Builder setDocumentClassVisibilityForPackage(Class<?>, boolean, androidx.appsearch.app.PackageIdentifier) throws androidx.appsearch.exceptions.AppSearchException;
     method public androidx.appsearch.app.SetSchemaRequest.Builder setForceOverride(boolean);
@@ -535,19 +570,20 @@
 
 package androidx.appsearch.observer {
 
-  public interface AppSearchObserverCallback {
-    method public void onDocumentChanged(androidx.appsearch.observer.DocumentChangeInfo);
-    method public void onSchemaChanged(androidx.appsearch.observer.SchemaChangeInfo);
-  }
-
   public final class DocumentChangeInfo {
-    ctor public DocumentChangeInfo(String, String, String, String);
+    ctor public DocumentChangeInfo(String, String, String, String, java.util.Set<java.lang.String!>);
+    method public java.util.Set<java.lang.String!> getChangedDocumentIds();
     method public String getDatabaseName();
     method public String getNamespace();
     method public String getPackageName();
     method public String getSchemaName();
   }
 
+  public interface ObserverCallback {
+    method public void onDocumentChanged(androidx.appsearch.observer.DocumentChangeInfo);
+    method public void onSchemaChanged(androidx.appsearch.observer.SchemaChangeInfo);
+  }
+
   public final class ObserverSpec {
     method public java.util.Set<java.lang.String!> getFilterSchemas();
   }
@@ -562,7 +598,8 @@
   }
 
   public final class SchemaChangeInfo {
-    ctor public SchemaChangeInfo(String, String);
+    ctor public SchemaChangeInfo(String, String, java.util.Set<java.lang.String!>);
+    method public java.util.Set<java.lang.String!> getChangedSchemaNames();
     method public String getDatabaseName();
     method public String getPackageName();
   }
diff --git a/appsearch/appsearch/api/public_plus_experimental_current.txt b/appsearch/appsearch/api/public_plus_experimental_current.txt
index 91b14d5..0529d14 100644
--- a/appsearch/appsearch/api/public_plus_experimental_current.txt
+++ b/appsearch/appsearch/api/public_plus_experimental_current.txt
@@ -177,18 +177,28 @@
 
   public interface AppSearchSession extends java.io.Closeable {
     method public void close();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,androidx.appsearch.app.GenericDocument!>!> getByDocumentId(androidx.appsearch.app.GetByDocumentIdRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,androidx.appsearch.app.GenericDocument!>!> getByDocumentId(androidx.appsearch.app.GetByDocumentIdRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,androidx.appsearch.app.GenericDocument!>!> getByDocumentIdAsync(androidx.appsearch.app.GetByDocumentIdRequest);
     method public androidx.appsearch.app.Features getFeatures();
-    method public com.google.common.util.concurrent.ListenableFuture<java.util.Set<java.lang.String!>!> getNamespaces();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchema();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.StorageInfo!> getStorageInfo();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> put(androidx.appsearch.app.PutDocumentsRequest);
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> remove(androidx.appsearch.app.RemoveByDocumentIdRequest);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> remove(String, androidx.appsearch.app.SearchSpec);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportUsage(androidx.appsearch.app.ReportUsageRequest);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> requestFlush();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.util.Set<java.lang.String!>!> getNamespaces();
+    method public com.google.common.util.concurrent.ListenableFuture<java.util.Set<java.lang.String!>!> getNamespacesAsync();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchema();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchemaAsync();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.StorageInfo!> getStorageInfo();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.StorageInfo!> getStorageInfoAsync();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> put(androidx.appsearch.app.PutDocumentsRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> putAsync(androidx.appsearch.app.PutDocumentsRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> remove(androidx.appsearch.app.RemoveByDocumentIdRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> remove(String, androidx.appsearch.app.SearchSpec);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> removeAsync(androidx.appsearch.app.RemoveByDocumentIdRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> removeAsync(String, androidx.appsearch.app.SearchSpec);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportUsage(androidx.appsearch.app.ReportUsageRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportUsageAsync(androidx.appsearch.app.ReportUsageRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> requestFlush();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> requestFlushAsync();
     method public androidx.appsearch.app.SearchResults search(String, androidx.appsearch.app.SearchSpec);
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.SetSchemaResponse!> setSchema(androidx.appsearch.app.SetSchemaRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.SetSchemaResponse!> setSchema(androidx.appsearch.app.SetSchemaRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.SetSchemaResponse!> setSchemaAsync(androidx.appsearch.app.SetSchemaRequest);
   }
 
   public interface DocumentClassFactory<T> {
@@ -200,7 +210,10 @@
 
   public interface Features {
     method public boolean isFeatureSupported(String);
-    field public static final String GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER = "GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER";
+    field public static final String ADD_PERMISSIONS_AND_GET_VISIBILITY = "ADD_PERMISSIONS_AND_GET_VISIBILITY";
+    field public static final String GLOBAL_SEARCH_SESSION_GET_BY_ID = "GLOBAL_SEARCH_SESSION_GET_BY_ID";
+    field public static final String GLOBAL_SEARCH_SESSION_GET_SCHEMA = "GLOBAL_SEARCH_SESSION_GET_SCHEMA";
+    field public static final String GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK = "GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK";
     field public static final String SEARCH_RESULT_MATCH_INFO_SUBMATCH = "SEARCH_RESULT_MATCH_INFO_SUBMATCH";
   }
 
@@ -266,6 +279,9 @@
   }
 
   public final class GetSchemaResponse {
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public java.util.Map<java.lang.String!,java.util.Set<java.util.Set<java.lang.Integer!>!>!> getRequiredPermissionsForSchemaTypeVisibility();
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public java.util.Set<java.lang.String!> getSchemaTypesNotDisplayedBySystem();
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public java.util.Map<java.lang.String!,java.util.Set<androidx.appsearch.app.PackageIdentifier!>!> getSchemaTypesVisibleToPackages();
     method public java.util.Set<androidx.appsearch.app.AppSearchSchema!> getSchemas();
     method @IntRange(from=0) public int getVersion();
   }
@@ -273,17 +289,24 @@
   public static final class GetSchemaResponse.Builder {
     ctor public GetSchemaResponse.Builder();
     method public androidx.appsearch.app.GetSchemaResponse.Builder addSchema(androidx.appsearch.app.AppSearchSchema);
+    method public androidx.appsearch.app.GetSchemaResponse.Builder addSchemaTypeNotDisplayedBySystem(String);
     method public androidx.appsearch.app.GetSchemaResponse build();
+    method public androidx.appsearch.app.GetSchemaResponse.Builder setRequiredPermissionsForSchemaTypeVisibility(String, java.util.Set<java.util.Set<java.lang.Integer!>!>);
+    method public androidx.appsearch.app.GetSchemaResponse.Builder setSchemaTypeVisibleToPackages(String, java.util.Set<androidx.appsearch.app.PackageIdentifier!>);
     method public androidx.appsearch.app.GetSchemaResponse.Builder setVersion(@IntRange(from=0) int);
   }
 
   public interface GlobalSearchSession extends java.io.Closeable {
-    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER) public void addObserver(String, androidx.appsearch.observer.ObserverSpec, java.util.concurrent.Executor, androidx.appsearch.observer.AppSearchObserverCallback);
     method public void close();
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_GET_BY_ID) public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,androidx.appsearch.app.GenericDocument!>!> getByDocumentIdAsync(String, String, androidx.appsearch.app.GetByDocumentIdRequest);
     method public androidx.appsearch.app.Features getFeatures();
-    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER) public void removeObserver(String, androidx.appsearch.observer.AppSearchObserverCallback);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportSystemUsage(androidx.appsearch.app.ReportSystemUsageRequest);
+    method @Deprecated @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA) public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchema(String, String);
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA) public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchemaAsync(String, String);
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK) public void registerObserverCallback(String, androidx.appsearch.observer.ObserverSpec, java.util.concurrent.Executor, androidx.appsearch.observer.ObserverCallback) throws androidx.appsearch.exceptions.AppSearchException;
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportSystemUsage(androidx.appsearch.app.ReportSystemUsageRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportSystemUsageAsync(androidx.appsearch.app.ReportSystemUsageRequest);
     method public androidx.appsearch.app.SearchResults search(String, androidx.appsearch.app.SearchSpec);
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK) public void unregisterObserverCallback(String, androidx.appsearch.observer.ObserverCallback) throws androidx.appsearch.exceptions.AppSearchException;
   }
 
   public abstract class Migrator {
@@ -395,7 +418,8 @@
 
   public interface SearchResults extends java.io.Closeable {
     method public void close();
-    method public com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.appsearch.app.SearchResult!>!> getNextPage();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.appsearch.app.SearchResult!>!> getNextPage();
+    method public com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.appsearch.app.SearchResult!>!> getNextPageAsync();
   }
 
   public final class SearchSpec {
@@ -453,20 +477,31 @@
 
   public final class SetSchemaRequest {
     method public java.util.Map<java.lang.String!,androidx.appsearch.app.Migrator!> getMigrators();
+    method public java.util.Map<java.lang.String!,java.util.Set<java.util.Set<java.lang.Integer!>!>!> getRequiredPermissionsForSchemaTypeVisibility();
     method public java.util.Set<androidx.appsearch.app.AppSearchSchema!> getSchemas();
     method public java.util.Set<java.lang.String!> getSchemasNotDisplayedBySystem();
     method public java.util.Map<java.lang.String!,java.util.Set<androidx.appsearch.app.PackageIdentifier!>!> getSchemasVisibleToPackages();
     method @IntRange(from=1) public int getVersion();
     method public boolean isForceOverride();
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_ASSISTANT_APP_SEARCH_DATA = 6; // 0x6
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_CALENDAR = 2; // 0x2
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_CONTACTS = 3; // 0x3
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_EXTERNAL_STORAGE = 4; // 0x4
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_HOME_APP_SEARCH_DATA = 5; // 0x5
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_SMS = 1; // 0x1
   }
 
   public static final class SetSchemaRequest.Builder {
     ctor public SetSchemaRequest.Builder();
     method public androidx.appsearch.app.SetSchemaRequest.Builder addDocumentClasses(Class<?>!...) throws androidx.appsearch.exceptions.AppSearchException;
     method public androidx.appsearch.app.SetSchemaRequest.Builder addDocumentClasses(java.util.Collection<? extends java.lang.Class<?>>) throws androidx.appsearch.exceptions.AppSearchException;
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public androidx.appsearch.app.SetSchemaRequest.Builder addRequiredPermissionsForDocumentClassVisibility(Class<?>, java.util.Set<java.lang.Integer!>) throws androidx.appsearch.exceptions.AppSearchException;
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public androidx.appsearch.app.SetSchemaRequest.Builder addRequiredPermissionsForSchemaTypeVisibility(String, java.util.Set<java.lang.Integer!>);
     method public androidx.appsearch.app.SetSchemaRequest.Builder addSchemas(androidx.appsearch.app.AppSearchSchema!...);
     method public androidx.appsearch.app.SetSchemaRequest.Builder addSchemas(java.util.Collection<androidx.appsearch.app.AppSearchSchema!>);
     method public androidx.appsearch.app.SetSchemaRequest build();
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public androidx.appsearch.app.SetSchemaRequest.Builder clearRequiredPermissionsForDocumentClassVisibility(Class<?>) throws androidx.appsearch.exceptions.AppSearchException;
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public androidx.appsearch.app.SetSchemaRequest.Builder clearRequiredPermissionsForSchemaTypeVisibility(String);
     method public androidx.appsearch.app.SetSchemaRequest.Builder setDocumentClassDisplayedBySystem(Class<?>, boolean) throws androidx.appsearch.exceptions.AppSearchException;
     method public androidx.appsearch.app.SetSchemaRequest.Builder setDocumentClassVisibilityForPackage(Class<?>, boolean, androidx.appsearch.app.PackageIdentifier) throws androidx.appsearch.exceptions.AppSearchException;
     method public androidx.appsearch.app.SetSchemaRequest.Builder setForceOverride(boolean);
@@ -535,19 +570,20 @@
 
 package androidx.appsearch.observer {
 
-  public interface AppSearchObserverCallback {
-    method public void onDocumentChanged(androidx.appsearch.observer.DocumentChangeInfo);
-    method public void onSchemaChanged(androidx.appsearch.observer.SchemaChangeInfo);
-  }
-
   public final class DocumentChangeInfo {
-    ctor public DocumentChangeInfo(String, String, String, String);
+    ctor public DocumentChangeInfo(String, String, String, String, java.util.Set<java.lang.String!>);
+    method public java.util.Set<java.lang.String!> getChangedDocumentIds();
     method public String getDatabaseName();
     method public String getNamespace();
     method public String getPackageName();
     method public String getSchemaName();
   }
 
+  public interface ObserverCallback {
+    method public void onDocumentChanged(androidx.appsearch.observer.DocumentChangeInfo);
+    method public void onSchemaChanged(androidx.appsearch.observer.SchemaChangeInfo);
+  }
+
   public final class ObserverSpec {
     method public java.util.Set<java.lang.String!> getFilterSchemas();
   }
@@ -562,7 +598,8 @@
   }
 
   public final class SchemaChangeInfo {
-    ctor public SchemaChangeInfo(String, String);
+    ctor public SchemaChangeInfo(String, String, java.util.Set<java.lang.String!>);
+    method public java.util.Set<java.lang.String!> getChangedSchemaNames();
     method public String getDatabaseName();
     method public String getPackageName();
   }
diff --git a/appsearch/appsearch/api/restricted_current.txt b/appsearch/appsearch/api/restricted_current.txt
index 91b14d5..0529d14 100644
--- a/appsearch/appsearch/api/restricted_current.txt
+++ b/appsearch/appsearch/api/restricted_current.txt
@@ -177,18 +177,28 @@
 
   public interface AppSearchSession extends java.io.Closeable {
     method public void close();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,androidx.appsearch.app.GenericDocument!>!> getByDocumentId(androidx.appsearch.app.GetByDocumentIdRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,androidx.appsearch.app.GenericDocument!>!> getByDocumentId(androidx.appsearch.app.GetByDocumentIdRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,androidx.appsearch.app.GenericDocument!>!> getByDocumentIdAsync(androidx.appsearch.app.GetByDocumentIdRequest);
     method public androidx.appsearch.app.Features getFeatures();
-    method public com.google.common.util.concurrent.ListenableFuture<java.util.Set<java.lang.String!>!> getNamespaces();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchema();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.StorageInfo!> getStorageInfo();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> put(androidx.appsearch.app.PutDocumentsRequest);
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> remove(androidx.appsearch.app.RemoveByDocumentIdRequest);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> remove(String, androidx.appsearch.app.SearchSpec);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportUsage(androidx.appsearch.app.ReportUsageRequest);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> requestFlush();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.util.Set<java.lang.String!>!> getNamespaces();
+    method public com.google.common.util.concurrent.ListenableFuture<java.util.Set<java.lang.String!>!> getNamespacesAsync();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchema();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchemaAsync();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.StorageInfo!> getStorageInfo();
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.StorageInfo!> getStorageInfoAsync();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> put(androidx.appsearch.app.PutDocumentsRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> putAsync(androidx.appsearch.app.PutDocumentsRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> remove(androidx.appsearch.app.RemoveByDocumentIdRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> remove(String, androidx.appsearch.app.SearchSpec);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,java.lang.Void!>!> removeAsync(androidx.appsearch.app.RemoveByDocumentIdRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> removeAsync(String, androidx.appsearch.app.SearchSpec);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportUsage(androidx.appsearch.app.ReportUsageRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportUsageAsync(androidx.appsearch.app.ReportUsageRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> requestFlush();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> requestFlushAsync();
     method public androidx.appsearch.app.SearchResults search(String, androidx.appsearch.app.SearchSpec);
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.SetSchemaResponse!> setSchema(androidx.appsearch.app.SetSchemaRequest);
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.SetSchemaResponse!> setSchema(androidx.appsearch.app.SetSchemaRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.SetSchemaResponse!> setSchemaAsync(androidx.appsearch.app.SetSchemaRequest);
   }
 
   public interface DocumentClassFactory<T> {
@@ -200,7 +210,10 @@
 
   public interface Features {
     method public boolean isFeatureSupported(String);
-    field public static final String GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER = "GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER";
+    field public static final String ADD_PERMISSIONS_AND_GET_VISIBILITY = "ADD_PERMISSIONS_AND_GET_VISIBILITY";
+    field public static final String GLOBAL_SEARCH_SESSION_GET_BY_ID = "GLOBAL_SEARCH_SESSION_GET_BY_ID";
+    field public static final String GLOBAL_SEARCH_SESSION_GET_SCHEMA = "GLOBAL_SEARCH_SESSION_GET_SCHEMA";
+    field public static final String GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK = "GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK";
     field public static final String SEARCH_RESULT_MATCH_INFO_SUBMATCH = "SEARCH_RESULT_MATCH_INFO_SUBMATCH";
   }
 
@@ -266,6 +279,9 @@
   }
 
   public final class GetSchemaResponse {
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public java.util.Map<java.lang.String!,java.util.Set<java.util.Set<java.lang.Integer!>!>!> getRequiredPermissionsForSchemaTypeVisibility();
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public java.util.Set<java.lang.String!> getSchemaTypesNotDisplayedBySystem();
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public java.util.Map<java.lang.String!,java.util.Set<androidx.appsearch.app.PackageIdentifier!>!> getSchemaTypesVisibleToPackages();
     method public java.util.Set<androidx.appsearch.app.AppSearchSchema!> getSchemas();
     method @IntRange(from=0) public int getVersion();
   }
@@ -273,17 +289,24 @@
   public static final class GetSchemaResponse.Builder {
     ctor public GetSchemaResponse.Builder();
     method public androidx.appsearch.app.GetSchemaResponse.Builder addSchema(androidx.appsearch.app.AppSearchSchema);
+    method public androidx.appsearch.app.GetSchemaResponse.Builder addSchemaTypeNotDisplayedBySystem(String);
     method public androidx.appsearch.app.GetSchemaResponse build();
+    method public androidx.appsearch.app.GetSchemaResponse.Builder setRequiredPermissionsForSchemaTypeVisibility(String, java.util.Set<java.util.Set<java.lang.Integer!>!>);
+    method public androidx.appsearch.app.GetSchemaResponse.Builder setSchemaTypeVisibleToPackages(String, java.util.Set<androidx.appsearch.app.PackageIdentifier!>);
     method public androidx.appsearch.app.GetSchemaResponse.Builder setVersion(@IntRange(from=0) int);
   }
 
   public interface GlobalSearchSession extends java.io.Closeable {
-    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER) public void addObserver(String, androidx.appsearch.observer.ObserverSpec, java.util.concurrent.Executor, androidx.appsearch.observer.AppSearchObserverCallback);
     method public void close();
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_GET_BY_ID) public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchBatchResult<java.lang.String!,androidx.appsearch.app.GenericDocument!>!> getByDocumentIdAsync(String, String, androidx.appsearch.app.GetByDocumentIdRequest);
     method public androidx.appsearch.app.Features getFeatures();
-    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER) public void removeObserver(String, androidx.appsearch.observer.AppSearchObserverCallback);
-    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportSystemUsage(androidx.appsearch.app.ReportSystemUsageRequest);
+    method @Deprecated @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA) public default com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchema(String, String);
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA) public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GetSchemaResponse!> getSchemaAsync(String, String);
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK) public void registerObserverCallback(String, androidx.appsearch.observer.ObserverSpec, java.util.concurrent.Executor, androidx.appsearch.observer.ObserverCallback) throws androidx.appsearch.exceptions.AppSearchException;
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportSystemUsage(androidx.appsearch.app.ReportSystemUsageRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportSystemUsageAsync(androidx.appsearch.app.ReportSystemUsageRequest);
     method public androidx.appsearch.app.SearchResults search(String, androidx.appsearch.app.SearchSpec);
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK) public void unregisterObserverCallback(String, androidx.appsearch.observer.ObserverCallback) throws androidx.appsearch.exceptions.AppSearchException;
   }
 
   public abstract class Migrator {
@@ -395,7 +418,8 @@
 
   public interface SearchResults extends java.io.Closeable {
     method public void close();
-    method public com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.appsearch.app.SearchResult!>!> getNextPage();
+    method @Deprecated public default com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.appsearch.app.SearchResult!>!> getNextPage();
+    method public com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.appsearch.app.SearchResult!>!> getNextPageAsync();
   }
 
   public final class SearchSpec {
@@ -453,20 +477,31 @@
 
   public final class SetSchemaRequest {
     method public java.util.Map<java.lang.String!,androidx.appsearch.app.Migrator!> getMigrators();
+    method public java.util.Map<java.lang.String!,java.util.Set<java.util.Set<java.lang.Integer!>!>!> getRequiredPermissionsForSchemaTypeVisibility();
     method public java.util.Set<androidx.appsearch.app.AppSearchSchema!> getSchemas();
     method public java.util.Set<java.lang.String!> getSchemasNotDisplayedBySystem();
     method public java.util.Map<java.lang.String!,java.util.Set<androidx.appsearch.app.PackageIdentifier!>!> getSchemasVisibleToPackages();
     method @IntRange(from=1) public int getVersion();
     method public boolean isForceOverride();
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_ASSISTANT_APP_SEARCH_DATA = 6; // 0x6
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_CALENDAR = 2; // 0x2
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_CONTACTS = 3; // 0x3
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_EXTERNAL_STORAGE = 4; // 0x4
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_HOME_APP_SEARCH_DATA = 5; // 0x5
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public static final int READ_SMS = 1; // 0x1
   }
 
   public static final class SetSchemaRequest.Builder {
     ctor public SetSchemaRequest.Builder();
     method public androidx.appsearch.app.SetSchemaRequest.Builder addDocumentClasses(Class<?>!...) throws androidx.appsearch.exceptions.AppSearchException;
     method public androidx.appsearch.app.SetSchemaRequest.Builder addDocumentClasses(java.util.Collection<? extends java.lang.Class<?>>) throws androidx.appsearch.exceptions.AppSearchException;
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public androidx.appsearch.app.SetSchemaRequest.Builder addRequiredPermissionsForDocumentClassVisibility(Class<?>, java.util.Set<java.lang.Integer!>) throws androidx.appsearch.exceptions.AppSearchException;
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public androidx.appsearch.app.SetSchemaRequest.Builder addRequiredPermissionsForSchemaTypeVisibility(String, java.util.Set<java.lang.Integer!>);
     method public androidx.appsearch.app.SetSchemaRequest.Builder addSchemas(androidx.appsearch.app.AppSearchSchema!...);
     method public androidx.appsearch.app.SetSchemaRequest.Builder addSchemas(java.util.Collection<androidx.appsearch.app.AppSearchSchema!>);
     method public androidx.appsearch.app.SetSchemaRequest build();
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public androidx.appsearch.app.SetSchemaRequest.Builder clearRequiredPermissionsForDocumentClassVisibility(Class<?>) throws androidx.appsearch.exceptions.AppSearchException;
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.ADD_PERMISSIONS_AND_GET_VISIBILITY) public androidx.appsearch.app.SetSchemaRequest.Builder clearRequiredPermissionsForSchemaTypeVisibility(String);
     method public androidx.appsearch.app.SetSchemaRequest.Builder setDocumentClassDisplayedBySystem(Class<?>, boolean) throws androidx.appsearch.exceptions.AppSearchException;
     method public androidx.appsearch.app.SetSchemaRequest.Builder setDocumentClassVisibilityForPackage(Class<?>, boolean, androidx.appsearch.app.PackageIdentifier) throws androidx.appsearch.exceptions.AppSearchException;
     method public androidx.appsearch.app.SetSchemaRequest.Builder setForceOverride(boolean);
@@ -535,19 +570,20 @@
 
 package androidx.appsearch.observer {
 
-  public interface AppSearchObserverCallback {
-    method public void onDocumentChanged(androidx.appsearch.observer.DocumentChangeInfo);
-    method public void onSchemaChanged(androidx.appsearch.observer.SchemaChangeInfo);
-  }
-
   public final class DocumentChangeInfo {
-    ctor public DocumentChangeInfo(String, String, String, String);
+    ctor public DocumentChangeInfo(String, String, String, String, java.util.Set<java.lang.String!>);
+    method public java.util.Set<java.lang.String!> getChangedDocumentIds();
     method public String getDatabaseName();
     method public String getNamespace();
     method public String getPackageName();
     method public String getSchemaName();
   }
 
+  public interface ObserverCallback {
+    method public void onDocumentChanged(androidx.appsearch.observer.DocumentChangeInfo);
+    method public void onSchemaChanged(androidx.appsearch.observer.SchemaChangeInfo);
+  }
+
   public final class ObserverSpec {
     method public java.util.Set<java.lang.String!> getFilterSchemas();
   }
@@ -562,7 +598,8 @@
   }
 
   public final class SchemaChangeInfo {
-    ctor public SchemaChangeInfo(String, String);
+    ctor public SchemaChangeInfo(String, String, java.util.Set<java.lang.String!>);
+    method public java.util.Set<java.lang.String!> getChangedSchemaNames();
     method public String getDatabaseName();
     method public String getPackageName();
   }
diff --git a/appsearch/appsearch/build.gradle b/appsearch/appsearch/build.gradle
index c5364677..02e32f9 100644
--- a/appsearch/appsearch/build.gradle
+++ b/appsearch/appsearch/build.gradle
@@ -32,9 +32,9 @@
     api('androidx.annotation:annotation:1.1.0')
     api(libs.guavaListenableFuture)
 
+    implementation('androidx.collection:collection:1.2.0')
     implementation('androidx.concurrent:concurrent-futures:1.0.0')
-    implementation('androidx.core:core:1.2.0')
-    implementation('androidx.collection:collection:1.0.0')
+    implementation('androidx.core:core:1.7.0')
 
     androidTestAnnotationProcessor project(':appsearch:appsearch-compiler')
     androidTestImplementation project(':appsearch:appsearch-local-storage')
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorLocalTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorLocalTest.java
index b22f8d8..6cf35bb 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorLocalTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorLocalTest.java
@@ -26,9 +26,9 @@
 
 public class AnnotationProcessorLocalTest extends AnnotationProcessorTestBase {
     @Override
-    protected ListenableFuture<AppSearchSession> createSearchSession(@NonNull String dbName) {
+    protected ListenableFuture<AppSearchSession> createSearchSessionAsync(@NonNull String dbName) {
         Context context = ApplicationProvider.getApplicationContext();
-        return LocalStorage.createSearchSession(
+        return LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, dbName).build());
     }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorPlatformTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorPlatformTest.java
index 5dbb8a2..e53c6aa 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorPlatformTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorPlatformTest.java
@@ -29,9 +29,9 @@
 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
 public class AnnotationProcessorPlatformTest extends AnnotationProcessorTestBase {
     @Override
-    protected ListenableFuture<AppSearchSession> createSearchSession(@NonNull String dbName) {
+    protected ListenableFuture<AppSearchSession> createSearchSessionAsync(@NonNull String dbName) {
         Context context = ApplicationProvider.getApplicationContext();
-        return PlatformStorage.createSearchSession(
+        return PlatformStorage.createSearchSessionAsync(
                 new PlatformStorage.SearchContext.Builder(context, dbName).build());
     }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorTestBase.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorTestBase.java
index 684e51f..82c0ae8 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorTestBase.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorTestBase.java
@@ -41,12 +41,12 @@
     private AppSearchSession mSession;
     private static final String DB_NAME_1 = "";
 
-    protected abstract ListenableFuture<AppSearchSession> createSearchSession(
+    protected abstract ListenableFuture<AppSearchSession> createSearchSessionAsync(
             @NonNull String dbName);
 
     @Before
     public void setUp() throws Exception {
-        mSession = createSearchSession(DB_NAME_1).get();
+        mSession = createSearchSessionAsync(DB_NAME_1).get();
 
         // Cleanup whatever documents may still exist in these databases. This is needed in
         // addition to tearDown in case a test exited without completing properly.
@@ -60,7 +60,8 @@
     }
 
     private void cleanup() throws Exception {
-        mSession.setSchema(new SetSchemaRequest.Builder().setForceOverride(true).build()).get();
+        mSession.setSchemaAsync(new SetSchemaRequest.Builder()
+                .setForceOverride(true).build()).get();
     }
 
     @Document
@@ -297,7 +298,7 @@
     public void testAnnotationProcessor() throws Exception {
         //TODO(b/156296904) add test for int, float, GenericDocument, and class with
         // @Document annotation
-        mSession.setSchema(
+        mSession.setSchemaAsync(
                 new SetSchemaRequest.Builder().addDocumentClasses(Card.class, Gift.class).build())
                 .get();
 
@@ -305,7 +306,7 @@
         Gift inputDocument = Gift.createPopulatedGift();
 
         // Index the Gift document and query it.
-        checkIsBatchResultSuccess(mSession.put(
+        checkIsBatchResultSuccess(mSession.putAsync(
                 new PutDocumentsRequest.Builder().addDocuments(inputDocument).build()));
         SearchResults searchResults = mSession.search("", new SearchSpec.Builder()
                 .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
@@ -320,7 +321,7 @@
 
     @Test
     public void testAnnotationProcessor_queryByType() throws Exception {
-        mSession.setSchema(
+        mSession.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addDocumentClasses(Card.class, Gift.class)
                         .addSchemas(AppSearchEmail.SCHEMA).build())
@@ -340,7 +341,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mSession.put(
+        checkIsBatchResultSuccess(mSession.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addDocuments(inputDocument1, inputDocument2)
                         .addGenericDocuments(email1).build()));
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AppSearchResultTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AppSearchResultInternalTest.java
similarity index 93%
rename from appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AppSearchResultTest.java
rename to appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AppSearchResultInternalTest.java
index 125e55f..12393de 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AppSearchResultTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AppSearchResultInternalTest.java
@@ -22,7 +22,8 @@
 
 import org.junit.Test;
 
-public class AppSearchResultTest {
+/** Tests for private APIs of {@link AppSearchResult}. */
+public class AppSearchResultInternalTest {
     @Test
     public void testMapNullPointerException() {
         NullPointerException e = assertThrows(NullPointerException.class, () -> {
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AutoValueDocumentInternalTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AutoValueDocumentInternalTest.java
new file mode 100644
index 0000000..2a8c632
--- /dev/null
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AutoValueDocumentInternalTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2022 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.appsearch.app;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.appsearch.annotation.Document;
+
+import com.google.auto.value.AutoValue;
+
+import org.junit.Test;
+
+
+public class AutoValueDocumentInternalTest{
+
+    /**
+     * Simple Document to demonstrate use of AutoValue and Document annotations, also nested
+     */
+    @Document
+    @AutoValue
+    public abstract static class SampleAutoValue {
+        @AutoValue.CopyAnnotations @Document.Id abstract String id();
+        @AutoValue.CopyAnnotations @Document.Namespace abstract String namespace();
+        @AutoValue.CopyAnnotations @Document.StringProperty abstract String property();
+
+        /** AutoValue constructor */
+        public static SampleAutoValue create(String id, String namespace, String property) {
+            return new AutoValue_AutoValueDocumentInternalTest_SampleAutoValue(id, namespace,
+                    property);
+        }
+    }
+
+    @Test
+    public void testGenericDocumentConversion_AutoValue() throws Exception {
+        SampleAutoValue sampleAutoValue = SampleAutoValue.create("id", "namespace", "property");
+        GenericDocument genericDocument = GenericDocument.fromDocumentClass(sampleAutoValue);
+        assertThat(genericDocument.getId()).isEqualTo("id");
+        assertThat(genericDocument.getNamespace()).isEqualTo("namespace");
+        assertThat(genericDocument.getSchemaType()).isEqualTo("SampleAutoValue");
+        assertThat(genericDocument.getProperty("property")).isEqualTo(new String[]{"property"});
+    }
+}
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/GenericDocumentTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/GenericDocumentInternalTest.java
similarity index 95%
rename from appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/GenericDocumentTest.java
rename to appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/GenericDocumentInternalTest.java
index c15f290..4d5b6c6 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/GenericDocumentTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/GenericDocumentInternalTest.java
@@ -23,7 +23,8 @@
 
 import org.junit.Test;
 
-public class GenericDocumentTest {
+/** Tests for private APIs of {@link GenericDocument}. */
+public class GenericDocumentInternalTest {
     @Test
     public void testRecreateFromParcel() {
         GenericDocument inDoc = new GenericDocument.Builder<>("namespace", "id1", "schema1")
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/GetSchemaResponseInternalTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/GetSchemaResponseInternalTest.java
new file mode 100644
index 0000000..f764313
--- /dev/null
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/GetSchemaResponseInternalTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2022 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.appsearch.app;
+
+import static org.junit.Assert.assertThrows;
+
+import org.junit.Test;
+
+/** Tests for private APIs of {@link GetSchemaResponse}. */
+public class GetSchemaResponseInternalTest {
+    // TODO(b/205749173): Expose this API and move this test to CTS. Without this API, clients can't
+    //   write unit tests that check their code in an environment where visibility settings are not
+    //   supported.
+    @Test
+    public void testRebuild_noSupportedException() {
+        AppSearchSchema schema1 = new AppSearchSchema.Builder("Email1")
+                .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("subject")
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(
+                                AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).build();
+
+        GetSchemaResponse.Builder builder =
+                new GetSchemaResponse.Builder(/*getVisibilitySettingSupported=*/false)
+                        .setVersion(42).addSchema(schema1);
+
+        GetSchemaResponse original = builder.build();
+        assertThrows(
+                UnsupportedOperationException.class,
+                () -> original.getSchemaTypesNotDisplayedBySystem());
+        assertThrows(
+                UnsupportedOperationException.class,
+                () -> original.getSchemaTypesVisibleToPackages());
+        assertThrows(
+                UnsupportedOperationException.class,
+                () -> original.getRequiredPermissionsForSchemaTypeVisibility());
+
+        // rebuild will throw same exception
+        GetSchemaResponse rebuild = builder.setVersion(42).build();
+        assertThrows(
+                UnsupportedOperationException.class,
+                () -> rebuild.getSchemaTypesNotDisplayedBySystem());
+        assertThrows(
+                UnsupportedOperationException.class,
+                () -> rebuild.getSchemaTypesVisibleToPackages());
+        assertThrows(
+                UnsupportedOperationException.class,
+                () -> original.getRequiredPermissionsForSchemaTypeVisibility());
+    }
+}
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SearchSpecTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SearchSpecInternalTest.java
similarity index 96%
rename from appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SearchSpecTest.java
rename to appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SearchSpecInternalTest.java
index 19ccc63..42de090 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SearchSpecTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SearchSpecInternalTest.java
@@ -22,7 +22,8 @@
 
 import org.junit.Test;
 
-public class SearchSpecTest {
+/** Tests for private APIs of {@link SearchSpec}. */
+public class SearchSpecInternalTest {
 
     @Test
     public void testGetBundle() {
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SetSchemaResponseTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SetSchemaResponseInternalTest.java
similarity index 96%
rename from appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SetSchemaResponseTest.java
rename to appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SetSchemaResponseInternalTest.java
index 8aa6148..799584a 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SetSchemaResponseTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SetSchemaResponseInternalTest.java
@@ -20,7 +20,8 @@
 
 import org.junit.Test;
 
-public class SetSchemaResponseTest {
+/** Tests for private APIs of {@link SetSchemaResponse}. */
+public class SetSchemaResponseInternalTest {
     @Test
     public void testRebuild() {
         SetSchemaResponse.MigrationFailure failure1 = new SetSchemaResponse.MigrationFailure(
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchResultCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchResultCtsTest.java
index 91dacdb..80094af1 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchResultCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchResultCtsTest.java
@@ -23,6 +23,14 @@
 import org.junit.Test;
 
 public class AppSearchResultCtsTest {
+    @Test
+    public void testNewSuccessfulResult() {
+        AppSearchResult<String> result = AppSearchResult.newSuccessfulResult("String");
+        assertThat(result.getResultCode()).isEqualTo(AppSearchResult.RESULT_OK);
+        assertThat(result.getResultValue()).isEqualTo("String");
+        assertThat(result.isSuccess()).isTrue();
+        assertThat(result.getErrorMessage()).isNull();
+    }
 
     @Test
     public void testResultEquals_identical() {
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationCtsTestBase.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationCtsTestBase.java
index a980a60..59c17f5 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationCtsTestBase.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationCtsTestBase.java
@@ -118,12 +118,12 @@
 
     private AppSearchSession mDb;
 
-    protected abstract ListenableFuture<AppSearchSession> createSearchSession(
+    protected abstract ListenableFuture<AppSearchSession> createSearchSessionAsync(
             @NonNull String dbName);
 
     @Before
     public void setUp() throws Exception {
-        mDb = createSearchSession(DB_NAME).get();
+        mDb = createSearchSessionAsync(DB_NAME).get();
 
         // Cleanup whatever documents may still exist in these databases. This is needed in
         // addition to tearDown in case a test exited without completing properly.
@@ -135,13 +135,13 @@
                         .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
                         .build())
                 .build();
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(schema).setForceOverride(true).build()).get();
         GenericDocument doc = new GenericDocument.Builder<>(
                 "namespace", "id0", "testSchema")
                 .setPropertyString("subject", "testPut example1")
                 .setCreationTimestampMillis(DOCUMENT_CREATION_TIME).build();
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(doc).build()));
         assertThat(result.getSuccesses()).containsExactly("id0", null);
         assertThat(result.getFailures()).isEmpty();
@@ -150,7 +150,7 @@
     @After
     public void tearDown() throws Exception {
         // Cleanup whatever documents may still exist in these databases.
-        mDb.setSchema(new SetSchemaRequest.Builder().setForceOverride(true).build()).get();
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder().setForceOverride(true).build()).get();
     }
 
     @Test
@@ -165,7 +165,7 @@
                         .build())
                 .build();
 
-        mDb.setSchema(
+        mDb.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(B_C_Schema)
                         .setMigrator("testSchema", ACTIVE_NOOP_MIGRATOR)
                         .setForceOverride(true)
@@ -185,7 +185,7 @@
                         .build())
                 .build();
 
-        mDb.setSchema(
+        mDb.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(B_NC_Schema)
                         .setMigrator("testSchema", ACTIVE_NOOP_MIGRATOR)
                         .setForceOverride(true)
@@ -198,7 +198,7 @@
         AppSearchSchema NB_C_Schema = new AppSearchSchema.Builder("testSchema")
                 .build();
 
-        mDb.setSchema(
+        mDb.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(NB_C_Schema)
                         .setMigrator("testSchema", ACTIVE_NOOP_MIGRATOR)
                         .setForceOverride(true)
@@ -212,7 +212,7 @@
         AppSearchSchema NB_C_Schema = new AppSearchSchema.Builder("testSchema")
                 .build();
 
-        mDb.setSchema(
+        mDb.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(NB_C_Schema)
                         .setMigrator("testSchema", INACTIVE_MIGRATOR)  //ND
                         .setForceOverride(true)
@@ -226,7 +226,7 @@
         AppSearchSchema NB_NC_Schema = new AppSearchSchema.Builder("testSchema")
                 .build();
 
-        mDb.setSchema(
+        mDb.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(NB_NC_Schema)
                         .setMigrator("testSchema", ACTIVE_NOOP_MIGRATOR)
                         .setForceOverride(true)
@@ -239,7 +239,7 @@
         AppSearchSchema $B_$C_Schema = new AppSearchSchema.Builder("testSchema")
                 .build();
 
-        mDb.setSchema(
+        mDb.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas($B_$C_Schema)
                         .setMigrator("testSchema", INACTIVE_MIGRATOR)  //ND
                         .setForceOverride(true)
@@ -258,7 +258,7 @@
                         .build())
                 .build();
 
-        mDb.setSchema(
+        mDb.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(B_C_Schema)
                         .setMigrator("testSchema", ACTIVE_NOOP_MIGRATOR)
                         .setVersion(2)     // upgrade version
@@ -277,7 +277,7 @@
                         .build())
                 .build();
 
-        mDb.setSchema(
+        mDb.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(B_NC_Schema)
                         .setMigrator("testSchema", ACTIVE_NOOP_MIGRATOR)
                         .setForceOverride(true)
@@ -290,7 +290,7 @@
         AppSearchSchema NB_C_Schema = new AppSearchSchema.Builder("testSchema")
                 .build();
 
-        mDb.setSchema(
+        mDb.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(NB_C_Schema)
                         .setMigrator("testSchema", ACTIVE_NOOP_MIGRATOR)
                         .setVersion(2)     // upgrade version
@@ -304,7 +304,7 @@
                 .build();
 
         ExecutionException exception = assertThrows(ExecutionException.class,
-                () -> mDb.setSchema(
+                () -> mDb.setSchemaAsync(
                         new SetSchemaRequest.Builder().addSchemas($B_C_Schema)
                                 .setMigrator("testSchema", INACTIVE_MIGRATOR)  //ND
                                 .setVersion(2)     // upgrade version
@@ -319,7 +319,7 @@
                 .build();
 
         ExecutionException exception = assertThrows(ExecutionException.class,
-                () -> mDb.setSchema(
+                () -> mDb.setSchemaAsync(
                         new SetSchemaRequest.Builder().addSchemas($B_$C_Schema)
                                 .setMigrator("testSchema", INACTIVE_MIGRATOR)  //ND
                                 .build()).get());
@@ -342,7 +342,7 @@
                         .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
                         .build())
                 .build();
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(schema).setForceOverride(true).build()).get();
 
         GenericDocument doc1 = new GenericDocument.Builder<>("namespace", "id1", "testSchema")
@@ -354,7 +354,7 @@
                 .setPropertyString("To", "testTo example2")
                 .build();
 
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(doc1, doc2).build()));
         assertThat(result.getSuccesses()).containsExactly("id1", null, "id2", null);
         assertThat(result.getFailures()).isEmpty();
@@ -406,13 +406,13 @@
         };
 
         SetSchemaResponse setSchemaResponse =
-                mDb.setSchema(new SetSchemaRequest.Builder().addSchemas(newSchema)
+                mDb.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(newSchema)
                         .setMigrator("testSchema", migrator)
                         .setVersion(2)     // upgrade version
                         .build()).get();
 
         // Check the schema has been saved
-        assertThat(mDb.getSchema().get().getSchemas()).containsExactly(newSchema);
+        assertThat(mDb.getSchemaAsync().get().getSchemas()).containsExactly(newSchema);
 
         assertThat(setSchemaResponse.getDeletedTypes()).isEmpty();
         assertThat(setSchemaResponse.getIncompatibleTypes())
@@ -458,7 +458,7 @@
                         .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
                         .build())
                 .build();
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(schema).setForceOverride(true).setVersion(3).build()).get();
 
         GenericDocument doc1 = new GenericDocument.Builder<>("namespace", "id1", "testSchema")
@@ -466,7 +466,7 @@
                 .setPropertyString("To", "testTo example1")
                 .build();
 
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(doc1).build()));
         assertThat(result.getSuccesses()).containsExactly("id1", null);
         assertThat(result.getFailures()).isEmpty();
@@ -508,13 +508,13 @@
         };
 
         SetSchemaResponse setSchemaResponse =
-                mDb.setSchema(new SetSchemaRequest.Builder().addSchemas(newSchema)
+                mDb.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(newSchema)
                         .setMigrator("testSchema", migrator)
                         .setVersion(1)     // downgrade version
                         .build()).get();
 
         // Check the schema has been saved
-        assertThat(mDb.getSchema().get().getSchemas()).containsExactly(newSchema);
+        assertThat(mDb.getSchemaAsync().get().getSchemas()).containsExactly(newSchema);
 
         assertThat(setSchemaResponse.getDeletedTypes()).isEmpty();
         assertThat(setSchemaResponse.getIncompatibleTypes())
@@ -546,7 +546,7 @@
                         .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
                         .build())
                 .build();
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(schema).setForceOverride(true).setVersion(3).build()).get();
 
         GenericDocument doc1 = new GenericDocument.Builder<>("namespace", "id1", "testSchema")
@@ -554,7 +554,7 @@
                 .setPropertyString("To", "testTo example1")
                 .build();
 
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(doc1).build()));
         assertThat(result.getSuccesses()).containsExactly("id1", null);
         assertThat(result.getFailures()).isEmpty();
@@ -594,7 +594,7 @@
 
         // SetSchema with forceOverride=false
         ExecutionException exception = assertThrows(ExecutionException.class,
-                () -> mDb.setSchema(new SetSchemaRequest.Builder().addSchemas(newSchema)
+                () -> mDb.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(newSchema)
                         .setMigrator("testSchema", migrator)
                         .setVersion(3)     // same version
                         .build()).get());
@@ -602,12 +602,12 @@
 
         // SetSchema with forceOverride=true
         SetSchemaResponse setSchemaResponse =
-                mDb.setSchema(new SetSchemaRequest.Builder().addSchemas(newSchema)
+                mDb.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(newSchema)
                         .setMigrator("testSchema", migrator)
                         .setVersion(3)     // same version
                         .setForceOverride(true).build()).get();
 
-        assertThat(mDb.getSchema().get().getSchemas()).containsExactly(newSchema);
+        assertThat(mDb.getSchemaAsync().get().getSchemas()).containsExactly(newSchema);
 
         assertThat(setSchemaResponse.getDeletedTypes()).isEmpty();
         assertThat(setSchemaResponse.getIncompatibleTypes())
@@ -632,7 +632,7 @@
                         .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
                         .build())
                 .build();
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(schema).setForceOverride(true).setVersion(2).build()).get();
 
         GenericDocument doc1 = new GenericDocument.Builder<>("namespace", "id1", "testSchema")
@@ -640,7 +640,7 @@
                 .setPropertyString("To", "testTo example1")
                 .build();
 
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(doc1).build()));
         assertThat(result.getSuccesses()).containsExactly("id1", null);
         assertThat(result.getFailures()).isEmpty();
@@ -680,7 +680,7 @@
 
         // SetSchema with forceOverride=false
         ExecutionException exception = assertThrows(ExecutionException.class,
-                () -> mDb.setSchema(new SetSchemaRequest.Builder().addSchemas(newSchema)
+                () -> mDb.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(newSchema)
                         .setMigrator("testSchema", migrator)
                         .setVersion(4)     // upgrade version
                         .build()).get());
@@ -692,14 +692,14 @@
         // set the source schema to AppSearch
         AppSearchSchema schema = new AppSearchSchema.Builder("sourceSchema")
                 .build();
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(schema).setForceOverride(true).build()).get();
 
         // save a doc to the source type
         GenericDocument doc = new GenericDocument.Builder<>(
                 "namespace", "id1", "sourceSchema")
                 .setCreationTimestampMillis(DOCUMENT_CREATION_TIME).build();
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(doc).build()));
         assertThat(result.getSuccesses()).containsExactly("id1", null);
         assertThat(result.getFailures()).isEmpty();
@@ -730,7 +730,7 @@
         // SetSchema with forceOverride=false
         // Source type exist, destination type doesn't exist.
         ExecutionException exception = assertThrows(ExecutionException.class,
-                () -> mDb.setSchema(new SetSchemaRequest.Builder()
+                () -> mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                         .addSchemas(new AppSearchSchema.Builder("emptySchema").build())
                         .setMigrator("sourceSchema", migrator_sourceToNowhere)
                         .setVersion(2).build())   // upgrade version
@@ -742,7 +742,7 @@
         // SetSchema with forceOverride=true
         // Source type exist, destination type doesn't exist.
         exception = assertThrows(ExecutionException.class,
-                () -> mDb.setSchema(new SetSchemaRequest.Builder()
+                () -> mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                         .addSchemas(new AppSearchSchema.Builder("emptySchema").build())
                         .setMigrator("sourceSchema", migrator_sourceToNowhere)
                         .setForceOverride(true)
@@ -758,7 +758,7 @@
         // set the destination schema to AppSearch
         AppSearchSchema destinationSchema =
                 new AppSearchSchema.Builder("destinationSchema").build();
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(destinationSchema).setForceOverride(true).build()).get();
 
         Migrator migrator_nowhereToDestination = new Migrator() {
@@ -787,7 +787,7 @@
         // no matter force override or not, the migrator won't be invoked
         // SetSchema with forceOverride=false
         SetSchemaResponse setSchemaResponse =
-                mDb.setSchema(new SetSchemaRequest.Builder().addSchemas(destinationSchema)
+                mDb.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(destinationSchema)
                         .addSchemas(new AppSearchSchema.Builder("emptySchema").build())
                         .setMigrator("nonExistSchema", migrator_nowhereToDestination)
                         .setVersion(2) //  upgrade version
@@ -796,7 +796,7 @@
 
         // SetSchema with forceOverride=true
         setSchemaResponse =
-                mDb.setSchema(new SetSchemaRequest.Builder().addSchemas(destinationSchema)
+                mDb.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(destinationSchema)
                         .addSchemas(new AppSearchSchema.Builder("emptySchema").build())
                         .setMigrator("nonExistSchema", migrator_nowhereToDestination)
                         .setVersion(2) //  upgrade version
@@ -807,7 +807,7 @@
     @Test
     public void testSchemaMigration_nowhereToNowhere() throws Exception {
         // set empty schema
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .setForceOverride(true).build()).get();
         Migrator migrator_nowhereToNowhere = new Migrator() {
             @Override
@@ -835,7 +835,7 @@
         // no matter force override or not, the migrator won't be invoked
         // SetSchema with forceOverride=false
         SetSchemaResponse setSchemaResponse =
-                mDb.setSchema(new SetSchemaRequest.Builder()
+                mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                         .addSchemas(new AppSearchSchema.Builder("emptySchema").build())
                         .setMigrator("nonExistSchema", migrator_nowhereToNowhere)
                         .setVersion(2)  //  upgrade version
@@ -844,7 +844,7 @@
 
         // SetSchema with forceOverride=true
         setSchemaResponse =
-                mDb.setSchema(new SetSchemaRequest.Builder()
+                mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                         .addSchemas(new AppSearchSchema.Builder("emptySchema").build())
                         .setMigrator("nonExistSchema", migrator_nowhereToNowhere)
                         .setVersion(2) //  upgrade version
@@ -857,13 +857,13 @@
         // set the source schema to AppSearch
         AppSearchSchema sourceSchema = new AppSearchSchema.Builder("sourceSchema")
                 .build();
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(sourceSchema).setForceOverride(true).build()).get();
 
         // save a doc to the source type
         GenericDocument doc = new GenericDocument.Builder<>(
                 "namespace", "id1", "sourceSchema").build();
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(doc).build()));
         assertThat(result.getSuccesses()).containsExactly("id1", null);
         assertThat(result.getFailures()).isEmpty();
@@ -897,7 +897,7 @@
         };
 
         // SetSchema with forceOverride=false and increase overall version
-        SetSchemaResponse setSchemaResponse = mDb.setSchema(new SetSchemaRequest.Builder()
+        SetSchemaResponse setSchemaResponse = mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(destinationSchema)
                 .setMigrator("sourceSchema", migrator)
                 .setForceOverride(false)
@@ -925,7 +925,7 @@
                         .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
                         .build())
                 .build();
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(sourceSchema).setForceOverride(true).build()).get();
 
         // save a child and an adult to the Person type
@@ -935,7 +935,7 @@
         GenericDocument adultDoc = new GenericDocument.Builder<>(
                 "namespace", "Person2", "Person")
                 .setPropertyLong("Age", 36).build();
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(childDoc, adultDoc).build()));
         assertThat(result.getSuccesses()).containsExactly("Person1", null, "Person2", null);
         assertThat(result.getFailures()).isEmpty();
@@ -987,7 +987,7 @@
                 .build();
 
         // SetSchema with forceOverride=false and increase overall version
-        SetSchemaResponse setSchemaResponse = mDb.setSchema(new SetSchemaRequest.Builder()
+        SetSchemaResponse setSchemaResponse = mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(adultSchema, childSchema)
                 .setMigrator("Person", migrator)
                 .setForceOverride(false)
@@ -1031,7 +1031,7 @@
                         .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
                         .build())
                 .build();
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(sourceSchemaA, sourceSchemaB).setForceOverride(true).build()).get();
 
         // save 100 docs to each type
@@ -1047,7 +1047,7 @@
                     .setCreationTimestampMillis(DOCUMENT_CREATION_TIME).build();
             putRequestBuilder.addGenericDocuments(docInA, docInB);
         }
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.putAsync(
                 putRequestBuilder.build()));
         assertThat(result.getFailures()).isEmpty();
 
@@ -1141,7 +1141,7 @@
         };
 
         // SetSchema with forceOverride=false and increase overall version
-        SetSchemaResponse setSchemaResponse = mDb.setSchema(new SetSchemaRequest.Builder()
+        SetSchemaResponse setSchemaResponse = mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(destinationSchemaB, destinationSchemaC, destinationSchemaD)
                 .setMigrator("schemaA", migratorA)
                 .setMigrator("schemaB", migratorB)
@@ -1280,7 +1280,7 @@
                         .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
                         .build())
                 .build();
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(typeA).setForceOverride(true).setVersion(1).build()).get();
 
         // save a doc to version 1.
@@ -1288,13 +1288,13 @@
                 "namespace", "id", "TypeA")
                 .setPropertyString("subject", "subject")
                 .setCreationTimestampMillis(DOCUMENT_CREATION_TIME).build();
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(doc).build()));
         assertThat(result.getSuccesses()).containsExactly("id", null);
         assertThat(result.getFailures()).isEmpty();
 
         // update to version 4.
-        SetSchemaResponse setSchemaResponse = mDb.setSchema(MULTI_STEP_REQUEST).get();
+        SetSchemaResponse setSchemaResponse = mDb.setSchemaAsync(MULTI_STEP_REQUEST).get();
         assertThat(setSchemaResponse.getDeletedTypes()).containsExactly("TypeA");
         assertThat(setSchemaResponse.getIncompatibleTypes()).isEmpty();
         assertThat(setSchemaResponse.getMigratedTypes()).containsExactly("TypeA");
@@ -1329,7 +1329,7 @@
                         .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
                         .build())
                 .build();
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(typeA).setForceOverride(true).setVersion(2).build()).get();
 
         // save a doc to version 2.
@@ -1338,13 +1338,13 @@
                 .setPropertyString("subject", "subject")
                 .setPropertyString("body", "bodyFromA")
                 .setCreationTimestampMillis(DOCUMENT_CREATION_TIME).build();
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(doc).build()));
         assertThat(result.getSuccesses()).containsExactly("id", null);
         assertThat(result.getFailures()).isEmpty();
 
         // update to version 4.
-        SetSchemaResponse setSchemaResponse = mDb.setSchema(MULTI_STEP_REQUEST).get();
+        SetSchemaResponse setSchemaResponse = mDb.setSchemaAsync(MULTI_STEP_REQUEST).get();
         assertThat(setSchemaResponse.getDeletedTypes()).containsExactly("TypeA");
         assertThat(setSchemaResponse.getIncompatibleTypes()).isEmpty();
         assertThat(setSchemaResponse.getMigratedTypes()).containsExactly("TypeA");
@@ -1375,7 +1375,7 @@
                         .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
                         .build())
                 .build();
-        mDb.setSchema(new SetSchemaRequest.Builder()
+        mDb.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(typeA).setForceOverride(true).setVersion(3).build()).get();
 
         // save a doc to version 2.
@@ -1384,13 +1384,13 @@
                 .setPropertyString("subject", "subject")
                 .setPropertyString("body", "bodyFromB")
                 .setCreationTimestampMillis(DOCUMENT_CREATION_TIME).build();
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(doc).build()));
         assertThat(result.getSuccesses()).containsExactly("id", null);
         assertThat(result.getFailures()).isEmpty();
 
         // update to version 4.
-        SetSchemaResponse setSchemaResponse = mDb.setSchema(MULTI_STEP_REQUEST).get();
+        SetSchemaResponse setSchemaResponse = mDb.setSchemaAsync(MULTI_STEP_REQUEST).get();
         assertThat(setSchemaResponse.getDeletedTypes()).isEmpty();
         assertThat(setSchemaResponse.getIncompatibleTypes()).containsExactly("TypeB");
         assertThat(setSchemaResponse.getMigratedTypes()).containsExactly("TypeB");
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationLocalCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationLocalCtsTest.java
index 6525ddd..b6821a0 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationLocalCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationLocalCtsTest.java
@@ -27,9 +27,9 @@
 
 public class AppSearchSchemaMigrationLocalCtsTest extends AppSearchSchemaMigrationCtsTestBase{
     @Override
-    protected ListenableFuture<AppSearchSession> createSearchSession(@NonNull String dbName) {
+    protected ListenableFuture<AppSearchSession> createSearchSessionAsync(@NonNull String dbName) {
         Context context = ApplicationProvider.getApplicationContext();
-        return LocalStorage.createSearchSession(
+        return LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, dbName).build());
     }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationPlatformCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationPlatformCtsTest.java
index 405d82e..f2b0e7a 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationPlatformCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationPlatformCtsTest.java
@@ -30,9 +30,9 @@
 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
 public class AppSearchSchemaMigrationPlatformCtsTest extends AppSearchSchemaMigrationCtsTestBase{
     @Override
-    protected ListenableFuture<AppSearchSession> createSearchSession(@NonNull String dbName) {
+    protected ListenableFuture<AppSearchSession> createSearchSessionAsync(@NonNull String dbName) {
         Context context = ApplicationProvider.getApplicationContext();
-        return PlatformStorage.createSearchSession(
+        return PlatformStorage.createSearchSessionAsync(
                 new PlatformStorage.SearchContext.Builder(context, dbName).build());
     }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionCtsTestBase.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionCtsTestBase.java
index 9d817be..8f535d6 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionCtsTestBase.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionCtsTestBase.java
@@ -26,6 +26,8 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
 
 import android.content.Context;
 
@@ -40,6 +42,7 @@
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.app.GetByDocumentIdRequest;
 import androidx.appsearch.app.GetSchemaResponse;
+import androidx.appsearch.app.PackageIdentifier;
 import androidx.appsearch.app.PutDocumentsRequest;
 import androidx.appsearch.app.RemoveByDocumentIdRequest;
 import androidx.appsearch.app.ReportUsageRequest;
@@ -54,6 +57,7 @@
 import androidx.test.core.app.ApplicationProvider;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.MoreExecutors;
 
@@ -62,6 +66,7 @@
 import org.junit.Test;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -78,16 +83,16 @@
     private AppSearchSession mDb1;
     private AppSearchSession mDb2;
 
-    protected abstract ListenableFuture<AppSearchSession> createSearchSession(
+    protected abstract ListenableFuture<AppSearchSession> createSearchSessionAsync(
             @NonNull String dbName);
 
-    protected abstract ListenableFuture<AppSearchSession> createSearchSession(
+    protected abstract ListenableFuture<AppSearchSession> createSearchSessionAsync(
             @NonNull String dbName, @NonNull ExecutorService executor);
 
     @Before
     public void setUp() throws Exception {
-        mDb1 = createSearchSession(DB_NAME_1).get();
-        mDb2 = createSearchSession(DB_NAME_2).get();
+        mDb1 = createSearchSessionAsync(DB_NAME_1).get();
+        mDb2 = createSearchSessionAsync(DB_NAME_2).get();
 
         // Cleanup whatever documents may still exist in these databases. This is needed in
         // addition to tearDown in case a test exited without completing properly.
@@ -101,9 +106,9 @@
     }
 
     private void cleanup() throws Exception {
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().setForceOverride(true).build()).get();
-        mDb2.setSchema(
+        mDb2.setSchemaAsync(
                 new SetSchemaRequest.Builder().setForceOverride(true).build()).get();
     }
 
@@ -121,19 +126,19 @@
                         .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
                         .build()
                 ).build();
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(emailSchema).build()).get();
     }
 
     @Test
     public void testSetSchema_Failure() throws Exception {
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
         AppSearchSchema emailSchema1 = new AppSearchSchema.Builder(AppSearchEmail.SCHEMA_TYPE)
                 .build();
 
         Throwable throwable = assertThrows(ExecutionException.class,
-                () -> mDb1.setSchema(new SetSchemaRequest.Builder()
+                () -> mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                         .addSchemas(emailSchema1).build()).get()).getCause();
         assertThat(throwable).isInstanceOf(AppSearchException.class);
         AppSearchException exception = (AppSearchException) throwable;
@@ -142,7 +147,7 @@
         assertThat(exception).hasMessageThat().contains("Incompatible types: {builtin:Email}");
 
         throwable = assertThrows(ExecutionException.class,
-                () -> mDb1.setSchema(new SetSchemaRequest.Builder().build()).get()).getCause();
+                () -> mDb1.setSchemaAsync(new SetSchemaRequest.Builder().build()).get()).getCause();
 
         assertThat(throwable).isInstanceOf(AppSearchException.class);
         exception = (AppSearchException) throwable;
@@ -166,17 +171,17 @@
                         .build()
                 ).build();
 
-        mDb1.setSchema(new SetSchemaRequest.Builder().addSchemas(schema)
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(schema)
                 .setVersion(1).build()).get();
 
-        Set<AppSearchSchema> actualSchemaTypes = mDb1.getSchema().get().getSchemas();
+        Set<AppSearchSchema> actualSchemaTypes = mDb1.getSchemaAsync().get().getSchemas();
         assertThat(actualSchemaTypes).containsExactly(schema);
 
         // increase version number
-        mDb1.setSchema(new SetSchemaRequest.Builder().addSchemas(schema)
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(schema)
                 .setVersion(2).build()).get();
 
-        GetSchemaResponse getSchemaResponse = mDb1.getSchema().get();
+        GetSchemaResponse getSchemaResponse = mDb1.getSchemaAsync().get();
         assertThat(getSchemaResponse.getSchemas()).containsExactly(schema);
         assertThat(getSchemaResponse.getVersion()).isEqualTo(2);
     }
@@ -197,18 +202,18 @@
                 ).build();
 
         // set different version number to different database.
-        mDb1.setSchema(new SetSchemaRequest.Builder().addSchemas(schema)
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(schema)
                 .setVersion(135).build()).get();
-        mDb2.setSchema(new SetSchemaRequest.Builder().addSchemas(schema)
+        mDb2.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(schema)
                 .setVersion(246).build()).get();
 
 
         // check the version has been set correctly.
-        GetSchemaResponse getSchemaResponse = mDb1.getSchema().get();
+        GetSchemaResponse getSchemaResponse = mDb1.getSchemaAsync().get();
         assertThat(getSchemaResponse.getSchemas()).containsExactly(schema);
         assertThat(getSchemaResponse.getVersion()).isEqualTo(135);
 
-        getSchemaResponse = mDb2.getSchema().get();
+        getSchemaResponse = mDb2.getSchemaAsync().get();
         assertThat(getSchemaResponse.getSchemas()).containsExactly(schema);
         assertThat(getSchemaResponse.getVersion()).isEqualTo(246);
     }
@@ -217,7 +222,7 @@
 
     @Test
     public void testSetSchema_addDocumentClasses() throws Exception {
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addDocumentClasses(EmailDocument.class).build()).get();
     }
 // @exportToFramework:endStrip()
@@ -256,13 +261,13 @@
         SetSchemaRequest request2 = new SetSchemaRequest.Builder()
                 .addSchemas(emailSchema2).addDocumentClasses(EmailDocument.class).build();
 
-        mDb1.setSchema(request1).get();
-        mDb2.setSchema(request2).get();
+        mDb1.setSchemaAsync(request1).get();
+        mDb2.setSchemaAsync(request2).get();
 
-        Set<AppSearchSchema> actual1 = mDb1.getSchema().get().getSchemas();
+        Set<AppSearchSchema> actual1 = mDb1.getSchemaAsync().get().getSchemas();
         assertThat(actual1).hasSize(2);
         assertThat(actual1).isEqualTo(request1.getSchemas());
-        Set<AppSearchSchema> actual2 = mDb2.getSchema().get().getSchemas();
+        Set<AppSearchSchema> actual2 = mDb2.getSchemaAsync().get().getSchemas();
         assertThat(actual2).hasSize(2);
         assertThat(actual2).isEqualTo(request2.getSchemas());
     }
@@ -296,9 +301,9 @@
                 .build();
 
         // Add it to AppSearch and then obtain it again
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(inSchema, AppSearchEmail.SCHEMA).build()).get();
-        GetSchemaResponse response = mDb1.getSchema().get();
+        GetSchemaResponse response = mDb1.getSchemaAsync().get();
         List<AppSearchSchema> schemas = new ArrayList<>(response.getSchemas());
         assertThat(schemas).containsExactly(inSchema, AppSearchEmail.SCHEMA);
         AppSearchSchema outSchema;
@@ -351,87 +356,213 @@
     }
 
     @Test
+    public void testGetSchema_visibilitySetting() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(
+                Features.ADD_PERMISSIONS_AND_GET_VISIBILITY));
+        AppSearchSchema emailSchema = new AppSearchSchema.Builder("Email1")
+                .addProperty(new StringPropertyConfig.Builder("subject")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).addProperty(new StringPropertyConfig.Builder("body")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).build();
+
+        byte[] shar256Cert1 = new byte[32];
+        Arrays.fill(shar256Cert1, (byte) 1);
+        byte[] shar256Cert2 = new byte[32];
+        Arrays.fill(shar256Cert2, (byte) 2);
+        PackageIdentifier packageIdentifier1 =
+                new PackageIdentifier("pkgFoo", shar256Cert1);
+        PackageIdentifier packageIdentifier2 =
+                new PackageIdentifier("pkgBar", shar256Cert2);
+        SetSchemaRequest request = new SetSchemaRequest.Builder()
+                .addSchemas(emailSchema)
+                .setSchemaTypeDisplayedBySystem("Email1", /*displayed=*/false)
+                .setSchemaTypeVisibilityForPackage("Email1", /*visible=*/true,
+                        packageIdentifier1)
+                .setSchemaTypeVisibilityForPackage("Email1", /*visible=*/true,
+                        packageIdentifier2)
+                .addRequiredPermissionsForSchemaTypeVisibility("Email1",
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR))
+                .addRequiredPermissionsForSchemaTypeVisibility("Email1",
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA))
+                .build();
+
+        mDb1.setSchemaAsync(request).get();
+
+        GetSchemaResponse getSchemaResponse = mDb1.getSchemaAsync().get();
+        Set<AppSearchSchema> actual = getSchemaResponse.getSchemas();
+        assertThat(actual).hasSize(1);
+        assertThat(actual).isEqualTo(request.getSchemas());
+        assertThat(getSchemaResponse.getSchemaTypesNotDisplayedBySystem())
+                .containsExactly("Email1");
+        assertThat(getSchemaResponse.getSchemaTypesVisibleToPackages())
+                .containsExactly("Email1", ImmutableSet.of(
+                        packageIdentifier1, packageIdentifier2));
+        assertThat(getSchemaResponse.getRequiredPermissionsForSchemaTypeVisibility())
+                .containsExactly("Email1", ImmutableSet.of(
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS,
+                                SetSchemaRequest.READ_CALENDAR),
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA)));
+    }
+
+    @Test
+    public void testGetSchema_visibilitySetting_notSupported() throws Exception {
+        assumeFalse(mDb1.getFeatures().isFeatureSupported(
+                Features.ADD_PERMISSIONS_AND_GET_VISIBILITY));
+        AppSearchSchema emailSchema = new AppSearchSchema.Builder("Email1")
+                .addProperty(new StringPropertyConfig.Builder("subject")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).addProperty(new StringPropertyConfig.Builder("body")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).build();
+
+        byte[] shar256Cert1 = new byte[32];
+        Arrays.fill(shar256Cert1, (byte) 1);
+        byte[] shar256Cert2 = new byte[32];
+        Arrays.fill(shar256Cert2, (byte) 2);
+        PackageIdentifier packageIdentifier1 =
+                new PackageIdentifier("pkgFoo", shar256Cert1);
+        PackageIdentifier packageIdentifier2 =
+                new PackageIdentifier("pkgBar", shar256Cert2);
+        SetSchemaRequest request = new SetSchemaRequest.Builder()
+                .addSchemas(emailSchema)
+                .setSchemaTypeDisplayedBySystem("Email1", /*displayed=*/false)
+                .setSchemaTypeVisibilityForPackage("Email1", /*visible=*/true,
+                        packageIdentifier1)
+                .setSchemaTypeVisibilityForPackage("Email1", /*visible=*/true,
+                        packageIdentifier2)
+                .build();
+
+        mDb1.setSchemaAsync(request).get();
+
+        GetSchemaResponse getSchemaResponse = mDb1.getSchemaAsync().get();
+        Set<AppSearchSchema> actual = getSchemaResponse.getSchemas();
+        assertThat(actual).hasSize(1);
+        assertThat(actual).isEqualTo(request.getSchemas());
+        assertThrows(
+                UnsupportedOperationException.class,
+                () -> getSchemaResponse.getSchemaTypesNotDisplayedBySystem());
+        assertThrows(
+                UnsupportedOperationException.class,
+                () -> getSchemaResponse.getSchemaTypesVisibleToPackages());
+        assertThrows(
+                UnsupportedOperationException.class,
+                () -> getSchemaResponse.getRequiredPermissionsForSchemaTypeVisibility());
+    }
+
+    @Test
+    public void testSetSchema_visibilitySettingPermission_notSupported() {
+        assumeFalse(mDb1.getFeatures().isFeatureSupported(
+                Features.ADD_PERMISSIONS_AND_GET_VISIBILITY));
+        AppSearchSchema emailSchema = new AppSearchSchema.Builder("Email1").build();
+
+        SetSchemaRequest request = new SetSchemaRequest.Builder()
+                .addSchemas(emailSchema)
+                .setSchemaTypeDisplayedBySystem("Email1", /*displayed=*/false)
+                .addRequiredPermissionsForSchemaTypeVisibility("Email1",
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS))
+                .build();
+
+        assertThrows(UnsupportedOperationException.class, () ->
+                mDb1.setSchemaAsync(request).get());
+    }
+
+    @Test
     public void testGetNamespaces() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
-        assertThat(mDb1.getNamespaces().get()).isEmpty();
+        assertThat(mDb1.getNamespacesAsync().get()).isEmpty();
 
         // Index a document
-        checkIsBatchResultSuccess(mDb1.put(new PutDocumentsRequest.Builder()
+        checkIsBatchResultSuccess(mDb1.putAsync(new PutDocumentsRequest.Builder()
                 .addGenericDocuments(new AppSearchEmail.Builder("namespace1", "id1").build())
                 .build()));
-        assertThat(mDb1.getNamespaces().get()).containsExactly("namespace1");
+        assertThat(mDb1.getNamespacesAsync().get()).containsExactly("namespace1");
 
         // Index additional data
-        checkIsBatchResultSuccess(mDb1.put(new PutDocumentsRequest.Builder()
+        checkIsBatchResultSuccess(mDb1.putAsync(new PutDocumentsRequest.Builder()
                 .addGenericDocuments(
                         new AppSearchEmail.Builder("namespace2", "id1").build(),
                         new AppSearchEmail.Builder("namespace2", "id2").build(),
                         new AppSearchEmail.Builder("namespace3", "id1").build())
                 .build()));
-        assertThat(mDb1.getNamespaces().get()).containsExactly(
+        assertThat(mDb1.getNamespacesAsync().get()).containsExactly(
                 "namespace1", "namespace2", "namespace3");
 
         // Remove namespace2/id2 -- namespace2 should still exist because of namespace2/id1
         checkIsBatchResultSuccess(
-                mDb1.remove(new RemoveByDocumentIdRequest.Builder("namespace2").addIds(
+                mDb1.removeAsync(new RemoveByDocumentIdRequest.Builder("namespace2").addIds(
                         "id2").build()));
-        assertThat(mDb1.getNamespaces().get()).containsExactly(
+        assertThat(mDb1.getNamespacesAsync().get()).containsExactly(
                 "namespace1", "namespace2", "namespace3");
 
         // Remove namespace2/id1 -- namespace2 should now be gone
         checkIsBatchResultSuccess(
-                mDb1.remove(new RemoveByDocumentIdRequest.Builder("namespace2").addIds(
+                mDb1.removeAsync(new RemoveByDocumentIdRequest.Builder("namespace2").addIds(
                         "id1").build()));
-        assertThat(mDb1.getNamespaces().get()).containsExactly("namespace1", "namespace3");
+        assertThat(mDb1.getNamespacesAsync().get()).containsExactly("namespace1", "namespace3");
 
         // Make sure the list of namespaces is preserved after restart
         mDb1.close();
-        mDb1 = createSearchSession(DB_NAME_1).get();
-        assertThat(mDb1.getNamespaces().get()).containsExactly("namespace1", "namespace3");
+        mDb1 = createSearchSessionAsync(DB_NAME_1).get();
+        assertThat(mDb1.getNamespacesAsync().get()).containsExactly("namespace1", "namespace3");
     }
 
     @Test
     public void testGetNamespaces_dbIsolation() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
-        mDb2.setSchema(
+        mDb2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
-        assertThat(mDb1.getNamespaces().get()).isEmpty();
-        assertThat(mDb2.getNamespaces().get()).isEmpty();
+        assertThat(mDb1.getNamespacesAsync().get()).isEmpty();
+        assertThat(mDb2.getNamespacesAsync().get()).isEmpty();
 
         // Index documents
-        checkIsBatchResultSuccess(mDb1.put(new PutDocumentsRequest.Builder()
+        checkIsBatchResultSuccess(mDb1.putAsync(new PutDocumentsRequest.Builder()
                 .addGenericDocuments(new AppSearchEmail.Builder("namespace1_db1", "id1").build())
                 .build()));
-        checkIsBatchResultSuccess(mDb1.put(new PutDocumentsRequest.Builder()
+        checkIsBatchResultSuccess(mDb1.putAsync(new PutDocumentsRequest.Builder()
                 .addGenericDocuments(new AppSearchEmail.Builder("namespace2_db1", "id1").build())
                 .build()));
-        checkIsBatchResultSuccess(mDb2.put(new PutDocumentsRequest.Builder()
+        checkIsBatchResultSuccess(mDb2.putAsync(new PutDocumentsRequest.Builder()
                 .addGenericDocuments(new AppSearchEmail.Builder("namespace_db2", "id1").build())
                 .build()));
-        assertThat(mDb1.getNamespaces().get()).containsExactly("namespace1_db1", "namespace2_db1");
-        assertThat(mDb2.getNamespaces().get()).containsExactly("namespace_db2");
+        assertThat(mDb1.getNamespacesAsync().get())
+                .containsExactly("namespace1_db1", "namespace2_db1");
+        assertThat(mDb2.getNamespacesAsync().get()).containsExactly("namespace_db2");
 
         // Make sure the list of namespaces is preserved after restart
         mDb1.close();
-        mDb1 = createSearchSession(DB_NAME_1).get();
-        assertThat(mDb1.getNamespaces().get()).containsExactly("namespace1_db1", "namespace2_db1");
-        assertThat(mDb2.getNamespaces().get()).containsExactly("namespace_db2");
+        mDb1 = createSearchSessionAsync(DB_NAME_1).get();
+        assertThat(mDb1.getNamespacesAsync().get())
+                .containsExactly("namespace1_db1", "namespace2_db1");
+        assertThat(mDb2.getNamespacesAsync().get()).containsExactly("namespace_db2");
     }
 
     @Test
     public void testGetSchema_emptyDB() throws Exception {
-        GetSchemaResponse getSchemaResponse = mDb1.getSchema().get();
+        GetSchemaResponse getSchemaResponse = mDb1.getSchemaAsync().get();
         assertThat(getSchemaResponse.getVersion()).isEqualTo(0);
     }
 
     @Test
     public void testPutDocuments() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index a document
@@ -442,18 +573,122 @@
                 .setBody("This is the body of the testPut email")
                 .build();
 
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb1.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email).build()));
         assertThat(result.getSuccesses()).containsExactly("id1", null);
         assertThat(result.getFailures()).isEmpty();
     }
 
+    @Test
+    public void testPutDocuments_emptyProperties() throws Exception {
+        // Schema registration. Due to b/204677124 is fixed in Android T. We have different
+        // behaviour when set empty array to bytes and documents between local and platform storage.
+        // This test only test String, long, boolean and double, for byte array and Document will be
+        // test in backend's specific test.
+        AppSearchSchema schema = new AppSearchSchema.Builder("testSchema")
+                .addProperty(new StringPropertyConfig.Builder("string")
+                        .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build())
+                .addProperty(new AppSearchSchema.LongPropertyConfig.Builder("long")
+                        .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
+                        .build())
+                .addProperty(new AppSearchSchema.DoublePropertyConfig.Builder("double")
+                        .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
+                        .build())
+                .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder("boolean")
+                        .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
+                        .build())
+                .build();
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
+                .addSchemas(schema, AppSearchEmail.SCHEMA).build()).get();
+
+        // Index a document
+        GenericDocument document = new GenericDocument.Builder<>("namespace", "id1", "testSchema")
+                .setPropertyBoolean("boolean")
+                .setPropertyString("string")
+                .setPropertyDouble("double")
+                .setPropertyLong("long")
+                .build();
+
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(document).build()));
+        assertThat(result.getSuccesses()).containsExactly("id1", null);
+        assertThat(result.getFailures()).isEmpty();
+
+        GetByDocumentIdRequest request = new GetByDocumentIdRequest.Builder("namespace")
+                .addIds("id1")
+                .build();
+        List<GenericDocument> outDocuments = doGet(mDb1, request);
+        assertThat(outDocuments).hasSize(1);
+        GenericDocument outDocument = outDocuments.get(0);
+        assertThat(outDocument.getPropertyBooleanArray("boolean")).isEmpty();
+        assertThat(outDocument.getPropertyStringArray("string")).isEmpty();
+        assertThat(outDocument.getPropertyDoubleArray("double")).isEmpty();
+        assertThat(outDocument.getPropertyLongArray("long")).isEmpty();
+    }
+
+    @Test
+    public void testPutLargeDocumentBatch() throws Exception {
+        // Schema registration
+        AppSearchSchema schema = new AppSearchSchema.Builder("Type").addProperty(
+                new StringPropertyConfig.Builder("body")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .build())
+                .build();
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(schema).build()).get();
+
+        // Creates a large batch of Documents, since we have max document size in Framework which is
+        // 512KiB, we will create 1KiB * 4000 docs = 4MiB total size > 1MiB binder transaction limit
+        char[] chars = new char[1024];  // 1KiB
+        Arrays.fill(chars, ' ');
+        String body = String.valueOf(chars) + "the end.";
+        List<GenericDocument> inDocuments = new ArrayList<>();
+        GetByDocumentIdRequest.Builder getByDocumentIdRequestBuilder =
+                new GetByDocumentIdRequest.Builder("namespace");
+        for (int i = 0; i < 4000; i++) {
+            GenericDocument inDocument = new GenericDocument.Builder<>(
+                    "namespace", "id" + i, "Type")
+                    .setPropertyString("body", body)
+                    .build();
+            inDocuments.add(inDocument);
+            getByDocumentIdRequestBuilder.addIds("id" + i);
+        }
+
+        // Index documents.
+        AppSearchBatchResult<String, Void> result =
+                mDb1.putAsync(new PutDocumentsRequest.Builder().addGenericDocuments(inDocuments)
+                        .build()).get();
+        assertThat(result.isSuccess()).isTrue();
+
+        // Query those documents and verify they are same with the input. This also verify
+        // AppSearchResult could handle large batch.
+        SearchResults searchResults = mDb1.search("end", new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .build());
+        List<GenericDocument> outDocuments = convertSearchResultsToDocuments(searchResults);
+        assertThat(inDocuments).containsExactlyElementsIn(outDocuments);
+
+        // Get by document ID and verify they are same with the input. This also verify
+        // AppSearchBatchResult could handle large batch.
+        AppSearchBatchResult<String, GenericDocument> batchResult = mDb1.getByDocumentIdAsync(
+                getByDocumentIdRequestBuilder.build()).get();
+        assertThat(batchResult.isSuccess()).isTrue();
+        for (int i = 0; i < inDocuments.size(); i++) {
+            GenericDocument inDocument = inDocuments.get(i);
+            assertThat(batchResult.getSuccesses().get(inDocument.getId())).isEqualTo(inDocument);
+        }
+    }
+
 // @exportToFramework:startStrip()
 
     @Test
     public void testPut_addDocumentClasses() throws Exception {
         // Schema registration
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addDocumentClasses(EmailDocument.class).build()).get();
 
         // Index a document
@@ -463,7 +698,7 @@
         email.subject = "testPut example";
         email.body = "This is the body of the testPut email";
 
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb1.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addDocuments(email).build()));
         assertThat(result.getSuccesses()).containsExactly("id1", null);
         assertThat(result.getFailures()).isEmpty();
@@ -497,7 +732,7 @@
                         .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
                         .build())
                 .build();
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(oldEmailSchema).build()).get();
 
         // Try to index a gift. This should fail as it's not in the schema.
@@ -505,19 +740,19 @@
                 new GenericDocument.Builder<>("namespace", "gift1", "Gift").setPropertyLong("price",
                         5).build();
         AppSearchBatchResult<String, Void> result =
-                mDb1.put(
+                mDb1.putAsync(
                         new PutDocumentsRequest.Builder().addGenericDocuments(gift).build()).get();
         assertThat(result.isSuccess()).isFalse();
         assertThat(result.getFailures().get("gift1").getResultCode())
                 .isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
 
         // Update the schema to include the gift and update email with a new field
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(newEmailSchema, giftSchema).build()).get();
 
         // Try to index the document again, which should now work
         checkIsBatchResultSuccess(
-                mDb1.put(
+                mDb1.putAsync(
                         new PutDocumentsRequest.Builder().addGenericDocuments(gift).build()));
 
         // Indexing an email with a body should also work
@@ -526,7 +761,7 @@
                 .setBody("This is the body of the testPut email")
                 .build();
         checkIsBatchResultSuccess(
-                mDb1.put(
+                mDb1.putAsync(
                         new PutDocumentsRequest.Builder().addGenericDocuments(email).build()));
     }
 
@@ -540,14 +775,14 @@
                         .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
                         .build())
                 .build();
-        mDb1.setSchema(new SetSchemaRequest.Builder().addSchemas(emailSchema).build()).get();
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(emailSchema).build()).get();
 
         // Index an email and check it present.
         AppSearchEmail email = new AppSearchEmail.Builder("namespace", "email1")
                 .setSubject("testPut example")
                 .build();
         checkIsBatchResultSuccess(
-                mDb1.put(
+                mDb1.putAsync(
                         new PutDocumentsRequest.Builder().addGenericDocuments(email).build()));
         List<GenericDocument> outDocuments =
                 doGet(mDb1, "namespace", "email1");
@@ -558,7 +793,7 @@
         // Try to remove the email schema. This should fail as it's an incompatible change.
         Throwable failResult1 = assertThrows(
                 ExecutionException.class,
-                () -> mDb1.setSchema(new SetSchemaRequest.Builder().build()).get()).getCause();
+                () -> mDb1.setSchemaAsync(new SetSchemaRequest.Builder().build()).get()).getCause();
         assertThat(failResult1).isInstanceOf(AppSearchException.class);
         assertThat(failResult1).hasMessageThat().contains("Schema is incompatible");
         assertThat(failResult1).hasMessageThat().contains(
@@ -566,10 +801,10 @@
 
         // Try to remove the email schema again, which should now work as we set forceOverride to
         // be true.
-        mDb1.setSchema(new SetSchemaRequest.Builder().setForceOverride(true).build()).get();
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder().setForceOverride(true).build()).get();
 
         // Make sure the indexed email is gone.
-        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentId(
+        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("namespace")
                         .addIds("email1")
                         .build()).get();
@@ -581,7 +816,7 @@
         AppSearchEmail email2 = new AppSearchEmail.Builder("namespace", "email2")
                 .setSubject("testPut example")
                 .build();
-        AppSearchBatchResult<String, Void> failResult2 = mDb1.put(
+        AppSearchBatchResult<String, Void> failResult2 = mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email2).build()).get();
         assertThat(failResult2.isSuccess()).isFalse();
         assertThat(failResult2.getFailures().get("email2").getErrorMessage())
@@ -599,15 +834,15 @@
                         .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
                         .build())
                 .build();
-        mDb1.setSchema(new SetSchemaRequest.Builder().addSchemas(emailSchema).build()).get();
-        mDb2.setSchema(new SetSchemaRequest.Builder().addSchemas(emailSchema).build()).get();
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(emailSchema).build()).get();
+        mDb2.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(emailSchema).build()).get();
 
         // Index an email and check it present in database1.
         AppSearchEmail email1 = new AppSearchEmail.Builder("namespace", "email1")
                 .setSubject("testPut example")
                 .build();
         checkIsBatchResultSuccess(
-                mDb1.put(
+                mDb1.putAsync(
                         new PutDocumentsRequest.Builder().addGenericDocuments(email1).build()));
         List<GenericDocument> outDocuments =
                 doGet(mDb1, "namespace", "email1");
@@ -620,7 +855,7 @@
                 .setSubject("testPut example")
                 .build();
         checkIsBatchResultSuccess(
-                mDb2.put(
+                mDb2.putAsync(
                         new PutDocumentsRequest.Builder().addGenericDocuments(email2).build()));
         outDocuments = doGet(mDb2, "namespace", "email2");
         assertThat(outDocuments).hasSize(1);
@@ -631,7 +866,7 @@
         // change.
         Throwable failResult1 = assertThrows(
                 ExecutionException.class,
-                () -> mDb1.setSchema(new SetSchemaRequest.Builder().build()).get()).getCause();
+                () -> mDb1.setSchemaAsync(new SetSchemaRequest.Builder().build()).get()).getCause();
         assertThat(failResult1).isInstanceOf(AppSearchException.class);
         assertThat(failResult1).hasMessageThat().contains("Schema is incompatible");
         assertThat(failResult1).hasMessageThat().contains(
@@ -639,10 +874,10 @@
 
         // Try to remove the email schema again, which should now work as we set forceOverride to
         // be true.
-        mDb1.setSchema(new SetSchemaRequest.Builder().setForceOverride(true).build()).get();
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder().setForceOverride(true).build()).get();
 
         // Make sure the indexed email is gone in database 1.
-        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentId(
+        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("namespace")
                         .addIds("email1").build()).get();
         assertThat(getResult.isSuccess()).isFalse();
@@ -653,7 +888,7 @@
         AppSearchEmail email3 = new AppSearchEmail.Builder("namespace", "email3")
                 .setSubject("testPut example")
                 .build();
-        AppSearchBatchResult<String, Void> failResult2 = mDb1.put(
+        AppSearchBatchResult<String, Void> failResult2 = mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email3).build()).get();
         assertThat(failResult2.isSuccess()).isFalse();
         assertThat(failResult2.getFailures().get("email3").getErrorMessage())
@@ -668,14 +903,14 @@
 
         // Make sure email could still be indexed in database 2.
         checkIsBatchResultSuccess(
-                mDb2.put(
+                mDb2.putAsync(
                         new PutDocumentsRequest.Builder().addGenericDocuments(email2).build()));
     }
 
     @Test
     public void testGetDocuments() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index a document
@@ -686,7 +921,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail).build()));
 
         // Get the document
@@ -696,7 +931,7 @@
         assertThat(outEmail).isEqualTo(inEmail);
 
         // Can't get the document in the other instance.
-        AppSearchBatchResult<String, GenericDocument> failResult = mDb2.getByDocumentId(
+        AppSearchBatchResult<String, GenericDocument> failResult = mDb2.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("namespace").addIds(
                         "id1").build()).get();
         assertThat(failResult.isSuccess()).isFalse();
@@ -709,7 +944,7 @@
     @Test
     public void testGet_addDocumentClasses() throws Exception {
         // Schema registration
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addDocumentClasses(EmailDocument.class).build()).get();
 
         // Index a document
@@ -718,7 +953,7 @@
         inEmail.id = "id1";
         inEmail.subject = "testPut example";
         inEmail.body = "This is the body of the testPut inEmail";
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addDocuments(inEmail).build()));
 
         // Get the document
@@ -735,7 +970,7 @@
     @Test
     public void testGetDocuments_projection() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .build()).get();
@@ -757,7 +992,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1, email2).build()));
 
@@ -789,7 +1024,7 @@
     @Test
     public void testGetDocuments_projectionEmpty() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .build()).get();
@@ -811,7 +1046,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1, email2).build()));
 
@@ -836,7 +1071,7 @@
     @Test
     public void testGetDocuments_projectionNonExistentType() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .build()).get();
@@ -858,7 +1093,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1, email2).build()));
 
@@ -890,7 +1125,7 @@
     @Test
     public void testGetDocuments_wildcardProjection() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .build()).get();
@@ -912,7 +1147,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1, email2).build()));
 
@@ -945,7 +1180,7 @@
     @Test
     public void testGetDocuments_wildcardProjectionEmpty() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .build()).get();
@@ -967,7 +1202,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1, email2).build()));
 
@@ -993,7 +1228,7 @@
     @Test
     public void testGetDocuments_wildcardProjectionNonExistentType() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .build()).get();
@@ -1015,7 +1250,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1, email2).build()));
 
@@ -1049,7 +1284,7 @@
     @Test
     public void testQuery() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index a document
@@ -1060,7 +1295,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail).build()));
 
         // Query for the document
@@ -1083,7 +1318,7 @@
     @Test
     public void testQuery_getNextPage() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
         Set<AppSearchEmail> emailSet = new HashSet<>();
         PutDocumentsRequest.Builder putDocumentsRequestBuilder = new PutDocumentsRequest.Builder();
@@ -1099,7 +1334,7 @@
             emailSet.add(inEmail);
             putDocumentsRequestBuilder.addGenericDocuments(inEmail);
         }
-        checkIsBatchResultSuccess(mDb1.put(putDocumentsRequestBuilder.build()));
+        checkIsBatchResultSuccess(mDb1.putAsync(putDocumentsRequestBuilder.build()));
 
         // Set number of results per page is 7.
         SearchResults searchResults = mDb1.search("body",
@@ -1114,7 +1349,7 @@
 
         // keep loading next page until it's empty.
         do {
-            results = searchResults.getNextPage().get();
+            results = searchResults.getNextPageAsync().get();
             ++pageNumber;
             for (SearchResult result : results) {
                 documents.add(result.getGenericDocument());
@@ -1129,7 +1364,7 @@
     @Test
     public void testQuery_relevanceScoring() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .build()).get();
@@ -1151,7 +1386,7 @@
                         .setSubject("I'm a little teapot")
                         .setBody("short and stout. Here is my handle, here is my spout.")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1, email2).build()));
 
@@ -1198,7 +1433,7 @@
                         .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
                         .build()
                 ).build();
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .addSchemas(genericSchema)
@@ -1214,7 +1449,7 @@
                         .build();
         GenericDocument inDoc = new GenericDocument.Builder<>("namespace", "id2", "Generic")
                 .setPropertyString("foo", "body").build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail, inDoc).build()));
 
         // Query for the documents
@@ -1246,7 +1481,7 @@
     @Test
     public void testQuery_packageFilter() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -1257,7 +1492,7 @@
                         .setSubject("foo")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email).build()));
 
         // Query for the document within our package
@@ -1273,14 +1508,14 @@
                 .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
                 .addFilterPackageNames("some.other.package")
                 .build());
-        List<SearchResult> results = searchResults.getNextPage().get();
+        List<SearchResult> results = searchResults.getNextPageAsync().get();
         assertThat(results).isEmpty();
     }
 
     @Test
     public void testQuery_namespaceFilter() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index two documents
@@ -1298,7 +1533,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(expectedEmail, unexpectedEmail).build()));
 
@@ -1333,7 +1568,7 @@
     @Test
     public void testQuery_getPackageName() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index a document
@@ -1344,7 +1579,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail).build()));
 
         // Query for the document
@@ -1356,7 +1591,7 @@
         List<GenericDocument> documents = new ArrayList<>();
         // keep loading next page until it's empty.
         do {
-            results = searchResults.getNextPage().get();
+            results = searchResults.getNextPageAsync().get();
             for (SearchResult result : results) {
                 assertThat(result.getGenericDocument()).isEqualTo(inEmail);
                 assertThat(result.getPackageName()).isEqualTo(
@@ -1370,7 +1605,7 @@
     @Test
     public void testQuery_getDatabaseName() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index a document
@@ -1381,7 +1616,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail).build()));
 
         // Query for the document
@@ -1393,7 +1628,7 @@
         List<GenericDocument> documents = new ArrayList<>();
         // keep loading next page until it's empty.
         do {
-            results = searchResults.getNextPage().get();
+            results = searchResults.getNextPageAsync().get();
             for (SearchResult result : results) {
                 assertThat(result.getGenericDocument()).isEqualTo(inEmail);
                 assertThat(result.getDatabaseName()).isEqualTo(DB_NAME_1);
@@ -1403,10 +1638,10 @@
         assertThat(documents).hasSize(1);
 
         // Schema registration for another database
-        mDb2.setSchema(
+        mDb2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail).build()));
 
         // Query for the document
@@ -1417,7 +1652,7 @@
         documents = new ArrayList<>();
         // keep loading next page until it's empty.
         do {
-            results = searchResults.getNextPage().get();
+            results = searchResults.getNextPageAsync().get();
             for (SearchResult result : results) {
                 assertThat(result.getGenericDocument()).isEqualTo(inEmail);
                 assertThat(result.getDatabaseName()).isEqualTo(DB_NAME_2);
@@ -1430,7 +1665,7 @@
     @Test
     public void testQuery_projection() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .addSchemas(new AppSearchSchema.Builder("Note")
@@ -1465,7 +1700,7 @@
                         .setCreationTimestampMillis(1000)
                         .setPropertyString("title", "Note title")
                         .setPropertyString("body", "Note body").build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email, note).build()));
 
@@ -1495,7 +1730,7 @@
     @Test
     public void testQuery_projectionEmpty() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .addSchemas(new AppSearchSchema.Builder("Note")
@@ -1530,7 +1765,7 @@
                         .setCreationTimestampMillis(1000)
                         .setPropertyString("title", "Note title")
                         .setPropertyString("body", "Note body").build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email, note).build()));
 
@@ -1558,7 +1793,7 @@
     @Test
     public void testQuery_projectionNonExistentType() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .addSchemas(new AppSearchSchema.Builder("Note")
@@ -1593,7 +1828,7 @@
                         .setCreationTimestampMillis(1000)
                         .setPropertyString("title", "Note title")
                         .setPropertyString("body", "Note body").build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email, note).build()));
 
@@ -1624,7 +1859,7 @@
     @Test
     public void testQuery_wildcardProjection() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .addSchemas(new AppSearchSchema.Builder("Note")
@@ -1658,7 +1893,7 @@
                         .setCreationTimestampMillis(1000)
                         .setPropertyString("title", "Note title")
                         .setPropertyString("body", "Note body").build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email, note).build()));
 
@@ -1688,7 +1923,7 @@
     @Test
     public void testQuery_wildcardProjectionEmpty() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .addSchemas(new AppSearchSchema.Builder("Note")
@@ -1720,7 +1955,7 @@
                         .setCreationTimestampMillis(1000)
                         .setPropertyString("title", "Note title")
                         .setPropertyString("body", "Note body").build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email, note).build()));
 
@@ -1745,7 +1980,7 @@
     @Test
     public void testQuery_wildcardProjectionNonExistentType() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .addSchemas(new AppSearchSchema.Builder("Note")
@@ -1780,7 +2015,7 @@
                         .setCreationTimestampMillis(1000)
                         .setPropertyString("title", "Note title")
                         .setPropertyString("body", "Note body").build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email, note).build()));
 
@@ -1811,9 +2046,9 @@
     @Test
     public void testQuery_twoInstances() throws Exception {
         // Schema registration
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
-        mDb2.setSchema(new SetSchemaRequest.Builder()
+        mDb2.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index a document to instance 1.
@@ -1824,7 +2059,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1).build()));
 
         // Index a document to instance 2.
@@ -1835,7 +2070,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail2).build()));
 
         // Query for instance 1.
@@ -1865,7 +2100,7 @@
                         .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
                         .build()
                 ).build();
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(genericSchema).build()).get();
 
         // Index a document
@@ -1874,7 +2109,7 @@
                         .setPropertyString("subject", "A commonly used fake word is foo. "
                                 + "Another nonsense word that’s used a lot is bar")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(document).build()));
 
         // Query for the document
@@ -1886,7 +2121,7 @@
                         .setMaxSnippetSize(10)
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .build());
-        List<SearchResult> results = searchResults.getNextPage().get();
+        List<SearchResult> results = searchResults.getNextPageAsync().get();
         assertThat(results).hasSize(1);
 
         List<SearchResult.MatchInfo> matchInfos = results.get(0).getMatchInfos();
@@ -1923,32 +2158,36 @@
                         .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
                         .build()
                 ).build();
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(genericSchema).build()).get();
 
         // Index documents
-        checkIsBatchResultSuccess(mDb1.put(new PutDocumentsRequest.Builder().addGenericDocuments(
-                new GenericDocument.Builder<>("namespace", "id1", "Generic")
-                        .setPropertyString(
-                                "subject",
-                                "I like cats", "I like dogs", "I like birds", "I like fish")
-                        .setScore(10)
-                        .build(),
-                new GenericDocument.Builder<>("namespace", "id2", "Generic")
-                        .setPropertyString(
-                                "subject",
-                                "I like red", "I like green", "I like blue", "I like yellow")
-                        .setScore(20)
-                        .build(),
-                new GenericDocument.Builder<>("namespace", "id3", "Generic")
-                        .setPropertyString(
-                                "subject",
-                                "I like cupcakes",
-                                "I like donuts",
-                                "I like eclairs",
-                                "I like froyo")
-                        .setScore(5)
-                        .build())
+        checkIsBatchResultSuccess(mDb1.putAsync(new PutDocumentsRequest.Builder()
+                .addGenericDocuments(
+                        new GenericDocument.Builder<>("namespace", "id1", "Generic")
+                                .setPropertyString(
+                                        "subject",
+                                        "I like cats", "I like dogs", "I like birds", "I like fish")
+                                .setScore(10)
+                                .build(),
+                        new GenericDocument.Builder<>("namespace", "id2", "Generic")
+                                .setPropertyString(
+                                        "subject",
+                                        "I like red",
+                                        "I like green",
+                                        "I like blue",
+                                        "I like yellow")
+                                .setScore(20)
+                                .build(),
+                        new GenericDocument.Builder<>("namespace", "id3", "Generic")
+                                .setPropertyString(
+                                        "subject",
+                                        "I like cupcakes",
+                                        "I like donuts",
+                                        "I like eclairs",
+                                        "I like froyo")
+                                .setScore(5)
+                                .build())
                 .build()));
 
         // Query for the document
@@ -1964,7 +2203,7 @@
                         .build());
 
         // Check result 1
-        List<SearchResult> results = searchResults.getNextPage().get();
+        List<SearchResult> results = searchResults.getNextPageAsync().get();
         assertThat(results).hasSize(3);
 
         assertThat(results.get(0).getGenericDocument().getId()).isEqualTo("id2");
@@ -1998,7 +2237,7 @@
                         .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
                         .build()
                 ).build();
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(genericSchema).build()).get();
 
         String japanese =
@@ -2011,7 +2250,7 @@
                 new GenericDocument.Builder<>("namespace", "id", "Generic")
                         .setPropertyString("subject", japanese)
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(document).build()));
 
         // Query for the document
@@ -2022,7 +2261,7 @@
                         .setSnippetCountPerProperty(1)
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .build());
-        List<SearchResult> results = searchResults.getNextPage().get();
+        List<SearchResult> results = searchResults.getNextPageAsync().get();
         assertThat(results).hasSize(1);
 
         List<SearchResult.MatchInfo> matchInfos = results.get(0).getMatchInfos();
@@ -2048,7 +2287,7 @@
     @Test
     public void testRemove() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -2066,7 +2305,7 @@
                         .setSubject("testPut example 2")
                         .setBody("This is the body of the testPut second email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1, email2).build()));
 
         // Check the presence of the documents
@@ -2074,12 +2313,12 @@
         assertThat(doGet(mDb1, "namespace", "id2")).hasSize(1);
 
         // Delete the document
-        checkIsBatchResultSuccess(mDb1.remove(
+        checkIsBatchResultSuccess(mDb1.removeAsync(
                 new RemoveByDocumentIdRequest.Builder("namespace").addIds(
                         "id1").build()));
 
         // Make sure it's really gone
-        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentId(
+        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("namespace").addIds("id1",
                         "id2").build())
                 .get();
@@ -2089,7 +2328,7 @@
         assertThat(getResult.getSuccesses().get("id2")).isEqualTo(email2);
 
         // Test if we delete a nonexistent id.
-        AppSearchBatchResult<String, Void> deleteResult = mDb1.remove(
+        AppSearchBatchResult<String, Void> deleteResult = mDb1.removeAsync(
                 new RemoveByDocumentIdRequest.Builder("namespace").addIds(
                         "id1").build()).get();
 
@@ -2100,7 +2339,7 @@
     @Test
     public void testRemove_multipleIds() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -2118,7 +2357,7 @@
                         .setSubject("testPut example 2")
                         .setBody("This is the body of the testPut second email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1, email2).build()));
 
         // Check the presence of the documents
@@ -2126,13 +2365,13 @@
         assertThat(doGet(mDb1, "namespace", "id2")).hasSize(1);
 
         // Delete the document
-        checkIsBatchResultSuccess(mDb1.remove(
+        checkIsBatchResultSuccess(mDb1.removeAsync(
                 new RemoveByDocumentIdRequest.Builder("namespace").addIds("id1", "id2").build()));
 
         // Make sure it's really gone
-        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentId(
-                new GetByDocumentIdRequest.Builder("namespace").addIds("id1",
-                        "id2").build())
+        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentIdAsync(
+                        new GetByDocumentIdRequest.Builder("namespace").addIds("id1",
+                                "id2").build())
                 .get();
         assertThat(getResult.isSuccess()).isFalse();
         assertThat(getResult.getFailures().get("id1").getResultCode())
@@ -2144,7 +2383,7 @@
     @Test
     public void testRemoveByQuery() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -2162,7 +2401,7 @@
                         .setSubject("bar")
                         .setBody("This is the body of the testPut second email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1, email2).build()));
 
         // Check the presence of the documents
@@ -2170,10 +2409,11 @@
         assertThat(doGet(mDb1, "namespace", "id2")).hasSize(1);
 
         // Delete the email 1 by query "foo"
-        mDb1.remove("foo",
+        mDb1.removeAsync("foo",
                 new SearchSpec.Builder().setTermMatch(SearchSpec.TERM_MATCH_PREFIX).build()).get();
-        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentId(
-                new GetByDocumentIdRequest.Builder("namespace").addIds("id1", "id2").build())
+        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentIdAsync(
+                        new GetByDocumentIdRequest.Builder("namespace")
+                                .addIds("id1", "id2").build())
                 .get();
         assertThat(getResult.isSuccess()).isFalse();
         assertThat(getResult.getFailures().get("id1").getResultCode())
@@ -2181,10 +2421,10 @@
         assertThat(getResult.getSuccesses().get("id2")).isEqualTo(email2);
 
         // Delete the email 2 by query "bar"
-        mDb1.remove("bar",
+        mDb1.removeAsync("bar",
                 new SearchSpec.Builder().setTermMatch(SearchSpec.TERM_MATCH_PREFIX).build()).get();
-        getResult = mDb1.getByDocumentId(
-                new GetByDocumentIdRequest.Builder("namespace").addIds("id2").build())
+        getResult = mDb1.getByDocumentIdAsync(
+                        new GetByDocumentIdRequest.Builder("namespace").addIds("id2").build())
                 .get();
         assertThat(getResult.isSuccess()).isFalse();
         assertThat(getResult.getFailures().get("id2").getResultCode())
@@ -2195,7 +2435,7 @@
     @Test
     public void testRemoveByQuery_nonExistNamespace() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -2213,7 +2453,7 @@
                         .setSubject("bar")
                         .setBody("This is the body of the testPut second email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1, email2).build()));
 
         // Check the presence of the documents
@@ -2221,7 +2461,7 @@
         assertThat(doGet(mDb1, "namespace2", "id2")).hasSize(1);
 
         // Delete the email by nonExist namespace.
-        mDb1.remove("",
+        mDb1.removeAsync("",
                 new SearchSpec.Builder().setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .addFilterNamespaces("nonExistNamespace").build()).get();
         // None of these emails will be deleted.
@@ -2232,7 +2472,7 @@
     @Test
     public void testRemoveByQuery_packageFilter() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -2243,7 +2483,7 @@
                         .setSubject("foo")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email).build()));
 
         // Check the presence of the documents
@@ -2251,17 +2491,17 @@
 
         // Try to delete email with query "foo", but restricted to a different package name.
         // Won't work and email will still exist.
-        mDb1.remove("foo",
+        mDb1.removeAsync("foo",
                 new SearchSpec.Builder().setTermMatch(
                         SearchSpec.TERM_MATCH_PREFIX).addFilterPackageNames(
                         "some.other.package").build()).get();
         assertThat(doGet(mDb1, "namespace", "id1")).hasSize(1);
 
         // Delete the email by query "foo", restricted to the correct package this time.
-        mDb1.remove("foo", new SearchSpec.Builder().setTermMatch(
+        mDb1.removeAsync("foo", new SearchSpec.Builder().setTermMatch(
                 SearchSpec.TERM_MATCH_PREFIX).addFilterPackageNames(
                 ApplicationProvider.getApplicationContext().getPackageName()).build()).get();
-        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentId(
+        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("namespace").addIds("id1", "id2").build())
                 .get();
         assertThat(getResult.isSuccess()).isFalse();
@@ -2272,7 +2512,7 @@
     @Test
     public void testRemove_twoInstances() throws Exception {
         // Schema registration
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -2283,32 +2523,32 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1).build()));
 
         // Check the presence of the documents
         assertThat(doGet(mDb1, "namespace", "id1")).hasSize(1);
 
         // Can't delete in the other instance.
-        AppSearchBatchResult<String, Void> deleteResult = mDb2.remove(
+        AppSearchBatchResult<String, Void> deleteResult = mDb2.removeAsync(
                 new RemoveByDocumentIdRequest.Builder("namespace").addIds("id1").build()).get();
         assertThat(deleteResult.getFailures().get("id1").getResultCode()).isEqualTo(
                 AppSearchResult.RESULT_NOT_FOUND);
         assertThat(doGet(mDb1, "namespace", "id1")).hasSize(1);
 
         // Delete the document
-        checkIsBatchResultSuccess(mDb1.remove(
+        checkIsBatchResultSuccess(mDb1.removeAsync(
                 new RemoveByDocumentIdRequest.Builder("namespace").addIds("id1").build()));
 
         // Make sure it's really gone
-        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentId(
+        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("namespace").addIds("id1").build()).get();
         assertThat(getResult.isSuccess()).isFalse();
         assertThat(getResult.getFailures().get("id1").getResultCode())
                 .isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
 
         // Test if we delete a nonexistent id.
-        deleteResult = mDb1.remove(
+        deleteResult = mDb1.removeAsync(
                 new RemoveByDocumentIdRequest.Builder("namespace").addIds("id1").build()).get();
         assertThat(deleteResult.getFailures().get("id1").getResultCode()).isEqualTo(
                 AppSearchResult.RESULT_NOT_FOUND);
@@ -2318,7 +2558,7 @@
     public void testRemoveByTypes() throws Exception {
         // Schema registration
         AppSearchSchema genericSchema = new AppSearchSchema.Builder("Generic").build();
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).addSchemas(
                         genericSchema).build()).get();
 
@@ -2339,7 +2579,7 @@
                         .build();
         GenericDocument document1 =
                 new GenericDocument.Builder<>("namespace", "id3", "Generic").build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1, email2, document1)
                         .build()));
 
@@ -2347,7 +2587,7 @@
         assertThat(doGet(mDb1, "namespace", "id1", "id2", "id3")).hasSize(3);
 
         // Delete the email type
-        mDb1.remove("",
+        mDb1.removeAsync("",
                 new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .addFilterSchemas(AppSearchEmail.SCHEMA_TYPE)
@@ -2355,7 +2595,7 @@
                 .get();
 
         // Make sure it's really gone
-        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentId(
+        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("namespace").addIds("id1", "id2", "id3").build())
                 .get();
         assertThat(getResult.isSuccess()).isFalse();
@@ -2369,9 +2609,9 @@
     @Test
     public void testRemoveByTypes_twoInstances() throws Exception {
         // Schema registration
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
-        mDb2.setSchema(new SetSchemaRequest.Builder()
+        mDb2.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -2389,9 +2629,9 @@
                         .setSubject("testPut example 2")
                         .setBody("This is the body of the testPut second email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1).build()));
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email2).build()));
 
         // Check the presence of the documents
@@ -2399,7 +2639,7 @@
         assertThat(doGet(mDb2, "namespace", "id2")).hasSize(1);
 
         // Delete the email type in instance 1
-        mDb1.remove("",
+        mDb1.removeAsync("",
                 new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .addFilterSchemas(AppSearchEmail.SCHEMA_TYPE)
@@ -2407,14 +2647,14 @@
                 .get();
 
         // Make sure it's really gone in instance 1
-        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentId(
+        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("namespace").addIds("id1").build()).get();
         assertThat(getResult.isSuccess()).isFalse();
         assertThat(getResult.getFailures().get("id1").getResultCode())
                 .isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
 
         // Make sure it's still in instance 2.
-        getResult = mDb2.getByDocumentId(
+        getResult = mDb2.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("namespace").addIds("id2").build()).get();
         assertThat(getResult.isSuccess()).isTrue();
         assertThat(getResult.getSuccesses().get("id2")).isEqualTo(email2);
@@ -2430,7 +2670,7 @@
                         .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
                         .build()
                 ).build();
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).addSchemas(
                         genericSchema).build()).get();
 
@@ -2452,7 +2692,7 @@
         GenericDocument document1 =
                 new GenericDocument.Builder<>("document", "id3", "Generic")
                         .setPropertyString("foo", "bar").build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1, email2, document1)
                         .build()));
 
@@ -2461,7 +2701,7 @@
         assertThat(doGet(mDb1, /*namespace=*/"document", "id3")).hasSize(1);
 
         // Delete the email namespace
-        mDb1.remove("",
+        mDb1.removeAsync("",
                 new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .addFilterNamespaces("email")
@@ -2469,7 +2709,7 @@
                 .get();
 
         // Make sure it's really gone
-        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentId(
+        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("email")
                         .addIds("id1", "id2").build()).get();
         assertThat(getResult.isSuccess()).isFalse();
@@ -2477,7 +2717,7 @@
                 .isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
         assertThat(getResult.getFailures().get("id2").getResultCode())
                 .isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
-        getResult = mDb1.getByDocumentId(
+        getResult = mDb1.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("document")
                         .addIds("id3").build()).get();
         assertThat(getResult.isSuccess()).isTrue();
@@ -2487,9 +2727,9 @@
     @Test
     public void testRemoveByNamespaces_twoInstances() throws Exception {
         // Schema registration
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
-        mDb2.setSchema(new SetSchemaRequest.Builder()
+        mDb2.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -2507,9 +2747,9 @@
                         .setSubject("testPut example 2")
                         .setBody("This is the body of the testPut second email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1).build()));
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email2).build()));
 
         // Check the presence of the documents
@@ -2517,7 +2757,7 @@
         assertThat(doGet(mDb2, /*namespace=*/"email", "id2")).hasSize(1);
 
         // Delete the email namespace in instance 1
-        mDb1.remove("",
+        mDb1.removeAsync("",
                 new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .addFilterNamespaces("email")
@@ -2525,7 +2765,7 @@
                 .get();
 
         // Make sure it's really gone in instance 1
-        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentId(
+        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("email")
                         .addIds("id1").build()).get();
         assertThat(getResult.isSuccess()).isFalse();
@@ -2533,7 +2773,7 @@
                 .isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
 
         // Make sure it's still in instance 2.
-        getResult = mDb2.getByDocumentId(
+        getResult = mDb2.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("email")
                         .addIds("id2").build()).get();
         assertThat(getResult.isSuccess()).isTrue();
@@ -2543,9 +2783,9 @@
     @Test
     public void testRemoveAll_twoInstances() throws Exception {
         // Schema registration
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
-        mDb2.setSchema(new SetSchemaRequest.Builder()
+        mDb2.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -2563,9 +2803,9 @@
                         .setSubject("testPut example 2")
                         .setBody("This is the body of the testPut second email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1).build()));
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email2).build()));
 
         // Check the presence of the documents
@@ -2573,21 +2813,21 @@
         assertThat(doGet(mDb2, "namespace", "id2")).hasSize(1);
 
         // Delete the all document in instance 1
-        mDb1.remove("",
+        mDb1.removeAsync("",
                 new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .build())
                 .get();
 
         // Make sure it's really gone in instance 1
-        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentId(
+        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("namespace").addIds("id1").build()).get();
         assertThat(getResult.isSuccess()).isFalse();
         assertThat(getResult.getFailures().get("id1").getResultCode())
                 .isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
 
         // Make sure it's still in instance 2.
-        getResult = mDb2.getByDocumentId(
+        getResult = mDb2.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("namespace").addIds("id2").build()).get();
         assertThat(getResult.isSuccess()).isTrue();
         assertThat(getResult.getSuccesses().get("id2")).isEqualTo(email2);
@@ -2596,9 +2836,9 @@
     @Test
     public void testRemoveAll_termMatchType() throws Exception {
         // Schema registration
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
-        mDb2.setSchema(new SetSchemaRequest.Builder()
+        mDb2.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -2630,9 +2870,9 @@
                         .setSubject("testPut example 4")
                         .setBody("This is the body of the testPut second email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1, email2).build()));
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email3, email4).build()));
 
         // Check the presence of the documents
@@ -2648,7 +2888,7 @@
         assertThat(documents).hasSize(2);
 
         // Delete the all document in instance 1 with TERM_MATCH_PREFIX
-        mDb1.remove("",
+        mDb1.removeAsync("",
                 new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .build())
@@ -2660,7 +2900,7 @@
         assertThat(documents).isEmpty();
 
         // Delete the all document in instance 2 with TERM_MATCH_EXACT_ONLY
-        mDb2.remove("",
+        mDb2.removeAsync("",
                 new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
                         .build())
@@ -2675,7 +2915,7 @@
     @Test
     public void testRemoveAllAfterEmpty() throws Exception {
         // Schema registration
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -2686,7 +2926,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1).build()));
 
         // Check the presence of the documents
@@ -2694,23 +2934,22 @@
 
         // Remove the document
         checkIsBatchResultSuccess(
-                mDb1.remove(new RemoveByDocumentIdRequest.Builder("namespace").addIds(
+                mDb1.removeAsync(new RemoveByDocumentIdRequest.Builder("namespace").addIds(
                         "id1").build()));
 
         // Make sure it's really gone
-        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentId(
+        AppSearchBatchResult<String, GenericDocument> getResult = mDb1.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("namespace").addIds("id1").build()).get();
         assertThat(getResult.isSuccess()).isFalse();
         assertThat(getResult.getFailures().get("id1").getResultCode())
                 .isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
 
         // Delete the all documents
-        mDb1.remove(
-                "", new SearchSpec.Builder().setTermMatch(SearchSpec.TERM_MATCH_PREFIX).build())
-                .get();
+        mDb1.removeAsync("", new SearchSpec.Builder()
+                        .setTermMatch(SearchSpec.TERM_MATCH_PREFIX).build()).get();
 
         // Make sure it's still gone
-        getResult = mDb1.getByDocumentId(
+        getResult = mDb1.getByDocumentIdAsync(
                 new GetByDocumentIdRequest.Builder("namespace").addIds("id1").build()).get();
         assertThat(getResult.isSuccess()).isFalse();
         assertThat(getResult.getFailures().get("id1").getResultCode())
@@ -2720,7 +2959,7 @@
     @Test
     public void testCloseAndReopen() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index a document
@@ -2731,12 +2970,12 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail).build()));
 
         // close and re-open the appSearchSession
         mDb1.close();
-        mDb1 = createSearchSession(DB_NAME_1).get();
+        mDb1 = createSearchSessionAsync(DB_NAME_1).get();
 
         // Query for the document
         SearchResults searchResults = mDb1.search("body", new SearchSpec.Builder()
@@ -2752,12 +2991,12 @@
         // Create a same-thread database by inject an executor which could help us maintain the
         // execution order of those async tasks.
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession sameThreadDb = createSearchSession(
+        AppSearchSession sameThreadDb = createSearchSessionAsync(
                 "sameThreadDb", MoreExecutors.newDirectExecutorService()).get();
 
         try {
             // Schema registration -- just mutate something
-            sameThreadDb.setSchema(
+            sameThreadDb.setSchemaAsync(
                     new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
             // Close the database. No further call will be allowed.
@@ -2773,15 +3012,16 @@
         } finally {
             // To clean the data that has been added in the test, need to re-open the session and
             // set an empty schema.
-            AppSearchSession reopen = createSearchSession(
+            AppSearchSession reopen = createSearchSessionAsync(
                     "sameThreadDb", MoreExecutors.newDirectExecutorService()).get();
-            reopen.setSchema(new SetSchemaRequest.Builder().setForceOverride(true).build()).get();
+            reopen.setSchemaAsync(new SetSchemaRequest.Builder()
+                    .setForceOverride(true).build()).get();
         }
     }
 
     @Test
     public void testReportUsage() throws Exception {
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index two documents.
@@ -2789,19 +3029,19 @@
                 new AppSearchEmail.Builder("namespace", "id1").build();
         AppSearchEmail email2 =
                 new AppSearchEmail.Builder("namespace", "id2").build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1, email2).build()));
 
         // Email 1 has more usages, but email 2 has more recent usages.
-        mDb1.reportUsage(new ReportUsageRequest.Builder("namespace", "id1")
+        mDb1.reportUsageAsync(new ReportUsageRequest.Builder("namespace", "id1")
                 .setUsageTimestampMillis(1000).build()).get();
-        mDb1.reportUsage(new ReportUsageRequest.Builder("namespace", "id1")
+        mDb1.reportUsageAsync(new ReportUsageRequest.Builder("namespace", "id1")
                 .setUsageTimestampMillis(2000).build()).get();
-        mDb1.reportUsage(new ReportUsageRequest.Builder("namespace", "id1")
+        mDb1.reportUsageAsync(new ReportUsageRequest.Builder("namespace", "id1")
                 .setUsageTimestampMillis(3000).build()).get();
-        mDb1.reportUsage(new ReportUsageRequest.Builder("namespace", "id2")
+        mDb1.reportUsageAsync(new ReportUsageRequest.Builder("namespace", "id2")
                 .setUsageTimestampMillis(10000).build()).get();
-        mDb1.reportUsage(new ReportUsageRequest.Builder("namespace", "id2")
+        mDb1.reportUsageAsync(new ReportUsageRequest.Builder("namespace", "id2")
                 .setUsageTimestampMillis(20000).build()).get();
 
         // Query by number of usages
@@ -2832,19 +3072,19 @@
 
     @Test
     public void testReportUsage_invalidNamespace() throws Exception {
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
         AppSearchEmail email1 = new AppSearchEmail.Builder("namespace", "id1").build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1).build()));
 
         // Use the correct namespace; it works
-        mDb1.reportUsage(new ReportUsageRequest.Builder("namespace", "id1").build()).get();
+        mDb1.reportUsageAsync(new ReportUsageRequest.Builder("namespace", "id1").build()).get();
 
         // Use an incorrect namespace; it fails
         ExecutionException e = assertThrows(
                 ExecutionException.class,
-                () -> mDb1.reportUsage(
+                () -> mDb1.reportUsageAsync(
                         new ReportUsageRequest.Builder("namespace2", "id1").build()).get());
         assertThat(e).hasCauseThat().isInstanceOf(AppSearchException.class);
         AppSearchException cause = (AppSearchException) e.getCause();
@@ -2853,26 +3093,26 @@
 
     @Test
     public void testGetStorageInfo() throws Exception {
-        StorageInfo storageInfo = mDb1.getStorageInfo().get();
+        StorageInfo storageInfo = mDb1.getStorageInfoAsync().get();
         assertThat(storageInfo.getSizeBytes()).isEqualTo(0);
 
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Still no storage space attributed with just a schema
-        storageInfo = mDb1.getStorageInfo().get();
+        storageInfo = mDb1.getStorageInfoAsync().get();
         assertThat(storageInfo.getSizeBytes()).isEqualTo(0);
 
         // Index two documents.
         AppSearchEmail email1 = new AppSearchEmail.Builder("namespace1", "id1").build();
         AppSearchEmail email2 = new AppSearchEmail.Builder("namespace1", "id2").build();
         AppSearchEmail email3 = new AppSearchEmail.Builder("namespace2", "id1").build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email1, email2,
                         email3).build()));
 
         // Non-zero size now
-        storageInfo = mDb1.getStorageInfo().get();
+        storageInfo = mDb1.getStorageInfoAsync().get();
         assertThat(storageInfo.getSizeBytes()).isGreaterThan(0);
         assertThat(storageInfo.getAliveDocumentsCount()).isEqualTo(3);
         assertThat(storageInfo.getAliveNamespacesCount()).isEqualTo(2);
@@ -2881,7 +3121,7 @@
     @Test
     public void testFlush() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index a document
@@ -2892,19 +3132,19 @@
                 .setBody("This is the body of the testPut email")
                 .build();
 
-        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb1.put(
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email).build()));
         assertThat(result.getSuccesses()).containsExactly("id1", null);
         assertThat(result.getFailures()).isEmpty();
 
         // The future returned from requestFlush will be set as a void or an Exception on error.
-        mDb1.requestFlush().get();
+        mDb1.requestFlushAsync().get();
     }
 
     @Test
     public void testQuery_ResultGroupingLimits() throws Exception {
         // Schema registration
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index four documents.
@@ -2915,7 +3155,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1).build()));
         AppSearchEmail inEmail2 =
                 new AppSearchEmail.Builder("namespace1", "id2")
@@ -2924,7 +3164,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail2).build()));
         AppSearchEmail inEmail3 =
                 new AppSearchEmail.Builder("namespace2", "id3")
@@ -2933,7 +3173,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail3).build()));
         AppSearchEmail inEmail4 =
                 new AppSearchEmail.Builder("namespace2", "id4")
@@ -2942,7 +3182,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail4).build()));
 
         // Query with per package result grouping. Only the last document 'email4' should be
@@ -2979,7 +3219,7 @@
     @Test
     public void testIndexNestedDocuments() throws Exception {
         // Schema registration
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA)
                 .addSchemas(new AppSearchSchema.Builder("YesNestedIndex")
                         .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(
@@ -3008,7 +3248,7 @@
                 new GenericDocument.Builder<>("namespace", "noNestedIndex", "NoNestedIndex")
                         .setPropertyDocument("prop", email)
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(new PutDocumentsRequest.Builder()
+        checkIsBatchResultSuccess(mDb1.putAsync(new PutDocumentsRequest.Builder()
                 .addGenericDocuments(yesNestedIndex, noNestedIndex).build()));
 
         // Query.
@@ -3017,7 +3257,7 @@
                 .setSnippetCount(10)
                 .setSnippetCountPerProperty(10)
                 .build());
-        List<SearchResult> page = searchResults.getNextPage().get();
+        List<SearchResult> page = searchResults.getNextPageAsync().get();
         assertThat(page).hasSize(1);
         assertThat(page.get(0).getGenericDocument()).isEqualTo(yesNestedIndex);
         List<SearchResult.MatchInfo> matches = page.get(0).getMatchInfos();
@@ -3030,7 +3270,7 @@
     @Test
     public void testCJKTQuery() throws Exception {
         // Schema registration
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index a document to instance 1.
@@ -3038,7 +3278,7 @@
                 new AppSearchEmail.Builder("namespace", "uri1")
                         .setBody("他是個男孩 is a boy")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1).build()));
 
         // Query for "ä»–" (He)
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionLocalCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionLocalCtsTest.java
index 8d45573..51745dd 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionLocalCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionLocalCtsTest.java
@@ -18,6 +18,7 @@
 
 import static androidx.appsearch.testutil.AppSearchTestUtils.checkIsBatchResultSuccess;
 import static androidx.appsearch.testutil.AppSearchTestUtils.convertSearchResultsToDocuments;
+import static androidx.appsearch.testutil.AppSearchTestUtils.doGet;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -30,6 +31,7 @@
 import androidx.appsearch.app.AppSearchSession;
 import androidx.appsearch.app.Features;
 import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.GetByDocumentIdRequest;
 import androidx.appsearch.app.Migrator;
 import androidx.appsearch.app.PutDocumentsRequest;
 import androidx.appsearch.app.SearchResult;
@@ -53,33 +55,51 @@
 
 public class AppSearchSessionLocalCtsTest extends AppSearchSessionCtsTestBase {
     @Override
-    protected ListenableFuture<AppSearchSession> createSearchSession(@NonNull String dbName) {
+    protected ListenableFuture<AppSearchSession> createSearchSessionAsync(@NonNull String dbName) {
         Context context = ApplicationProvider.getApplicationContext();
-        return LocalStorage.createSearchSession(
+        return LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, dbName).build());
     }
 
     @Override
-    protected ListenableFuture<AppSearchSession> createSearchSession(
+    protected ListenableFuture<AppSearchSession> createSearchSessionAsync(
             @NonNull String dbName, @NonNull ExecutorService executor) {
         Context context = ApplicationProvider.getApplicationContext();
-        return LocalStorage.createSearchSession(
+        return LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, dbName)
                         .setWorkerExecutor(executor).build());
     }
 
+    @Test
+    public void testFeaturesSupported() throws Exception {
+        Context context = ApplicationProvider.getApplicationContext();
+        AppSearchSession db2 = LocalStorage.createSearchSessionAsync(
+                new LocalStorage.SearchContext.Builder(context, DB_NAME_2).build()).get();
+
+        assertThat(db2.getFeatures().isFeatureSupported(
+                Features.SEARCH_RESULT_MATCH_INFO_SUBMATCH)).isTrue();
+        assertThat(db2.getFeatures().isFeatureSupported(
+                Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK)).isTrue();
+        assertThat(db2.getFeatures().isFeatureSupported(
+                Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA)).isTrue();
+        assertThat(db2.getFeatures().isFeatureSupported(
+                Features.GLOBAL_SEARCH_SESSION_GET_BY_ID)).isTrue();
+        assertThat(db2.getFeatures().isFeatureSupported(
+                Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)).isTrue();
+    }
+
     // TODO(b/194207451) This test can be moved to CtsTestBase if customized logger is
     //  supported for platform backend.
     @Test
     public void testLogger_searchStatsLogged_forEmptyFirstPage() throws Exception {
         SimpleTestLogger logger = new SimpleTestLogger();
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = LocalStorage.createSearchSession(
+        AppSearchSession db2 = LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, DB_NAME_2)
                         .setLogger(logger).build()).get();
 
         // Schema registration
-        db2.setSchema(
+        db2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -97,7 +117,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(db2.put(
+        checkIsBatchResultSuccess(db2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1, inEmail2).build()));
 
         assertThat(logger.mSearchStats).isNull();
@@ -111,7 +131,7 @@
                 .build());
 
         // Get first page
-        List<SearchResult> page = searchResults.getNextPage().get();
+        List<SearchResult> page = searchResults.getNextPageAsync().get();
         assertThat(page).hasSize(0);
 
         // Check searchStats has been set. We won't check all the fields here.
@@ -133,12 +153,12 @@
     public void testLogger_searchStatsLogged_forNonEmptyFirstPage() throws Exception {
         SimpleTestLogger logger = new SimpleTestLogger();
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = LocalStorage.createSearchSession(
+        AppSearchSession db2 = LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, DB_NAME_2)
                         .setLogger(logger).build()).get();
 
         // Schema registration
-        db2.setSchema(
+        db2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -156,7 +176,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(db2.put(
+        checkIsBatchResultSuccess(db2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1, inEmail2).build()));
 
         assertThat(logger.mSearchStats).isNull();
@@ -170,7 +190,7 @@
                 .build());
 
         // Get first page
-        List<SearchResult> page = searchResults.getNextPage().get();
+        List<SearchResult> page = searchResults.getNextPageAsync().get();
         assertThat(page).hasSize(2);
 
         // Check searchStats has been set. We won't check all the fields here.
@@ -192,12 +212,12 @@
     public void testLogger_searchStatsLogged_forEmptySecondPage() throws Exception {
         SimpleTestLogger logger = new SimpleTestLogger();
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = LocalStorage.createSearchSession(
+        AppSearchSession db2 = LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, DB_NAME_2)
                         .setLogger(logger).build()).get();
 
         // Schema registration
-        db2.setSchema(
+        db2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -215,7 +235,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(db2.put(
+        checkIsBatchResultSuccess(db2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1, inEmail2).build()));
 
         // Query for the document
@@ -228,12 +248,12 @@
                 .build());
 
         // Get first page
-        List<SearchResult> page = searchResults.getNextPage().get();
+        List<SearchResult> page = searchResults.getNextPageAsync().get();
         assertThat(page).hasSize(2);
 
         // Get second(empty) page
         logger.mSearchStats = null;
-        page = searchResults.getNextPage().get();
+        page = searchResults.getNextPageAsync().get();
         assertThat(page).hasSize(0);
 
         // Check searchStats has been set. We won't check all the fields here.
@@ -255,12 +275,12 @@
     public void testLogger_searchStatsLogged_forNonEmptySecondPage() throws Exception {
         SimpleTestLogger logger = new SimpleTestLogger();
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = LocalStorage.createSearchSession(
+        AppSearchSession db2 = LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, DB_NAME_2)
                         .setLogger(logger).build()).get();
 
         // Schema registration
-        db2.setSchema(
+        db2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -278,7 +298,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(db2.put(
+        checkIsBatchResultSuccess(db2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1, inEmail2).build()));
 
         // Query for the document
@@ -291,12 +311,12 @@
                 .build());
 
         // Get first page
-        List<SearchResult> page = searchResults.getNextPage().get();
+        List<SearchResult> page = searchResults.getNextPageAsync().get();
         assertThat(page).hasSize(1);
 
         // Get second page
         logger.mSearchStats = null;
-        page = searchResults.getNextPage().get();
+        page = searchResults.getNextPageAsync().get();
         assertThat(page).hasSize(1);
 
         // Check searchStats has been set. We won't check all the fields here.
@@ -318,7 +338,7 @@
     public void testSetSchemaStats_withoutSchemaMigration() throws Exception {
         SimpleTestLogger logger = new SimpleTestLogger();
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = LocalStorage.createSearchSession(
+        AppSearchSession db2 = LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, DB_NAME_2)
                         .setLogger(logger).build()).get();
         AppSearchSchema appSearchSchema = new AppSearchSchema.Builder("testSchema")
@@ -330,7 +350,7 @@
                         .build())
                 .build();
 
-        db2.setSchema(
+        db2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(appSearchSchema).build()).get();
 
         assertThat(logger.mSetSchemaStats).isNotNull();
@@ -352,7 +372,7 @@
     public void testSetSchemaStats_withSchemaMigration() throws Exception {
         SimpleTestLogger logger = new SimpleTestLogger();
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = LocalStorage.createSearchSession(
+        AppSearchSession db2 = LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, DB_NAME_2)
                         .setLogger(logger).build()).get();
         AppSearchSchema schema = new AppSearchSchema.Builder("testSchema")
@@ -407,11 +427,11 @@
             }
         };
 
-        db2.setSchema(new SetSchemaRequest.Builder().addSchemas(
+        db2.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(
                 schema).setForceOverride(true).build()).get();
-        checkIsBatchResultSuccess(db2.put(
+        checkIsBatchResultSuccess(db2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(doc).build()));
-        db2.setSchema(new SetSchemaRequest.Builder().addSchemas(newSchema)
+        db2.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(newSchema)
                 .setMigrator("testSchema", migrator)
                 .setVersion(2)     // upgrade version
                 .build()).get();
@@ -424,16 +444,15 @@
         assertThat(schemaMigrationStats.getSavedDocumentCount()).isEqualTo(1);
     }
 
-    // TODO(b/185441119) Following test can be moved to CtsTestBase if we fix the binder
-    //  transaction limit in framework.
+    // Framework has max Document size which is 512KiB, this test should only exists in Jetpack.
     @Test
-    public void testPutLargeDocument() throws Exception {
+    public void testPutLargeDocumentToIcing() throws Exception {
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = LocalStorage.createSearchSession(
+        AppSearchSession db2 = LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, DB_NAME_2).build()).get();
 
         // Schema registration
-        db2.setSchema(
+        db2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         char[] chars = new char[16_000_000];
@@ -447,7 +466,7 @@
                 .setSubject("testPut example")
                 .setBody(body)
                 .build();
-        AppSearchBatchResult<String, Void> result = db2.put(
+        AppSearchBatchResult<String, Void> result = db2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email).build()).get();
         assertThat(result.isSuccess()).isTrue();
 
@@ -460,16 +479,15 @@
         assertThat(outEmail).isEqualTo(email);
     }
 
-    // TODO(b/185441119) Following test can be moved to CtsTestBase if we fix the binder
-    //  transaction limit in framework.
+    // Framework has max Document size which is 512KiB, this test should only exists in Jetpack.
     @Test
-    public void testPutLargeDocument_exceedLimit() throws Exception {
+    public void testPutLargeDocumentToIcing_exceedLimit() throws Exception {
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = LocalStorage.createSearchSession(
+        AppSearchSession db2 = LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, DB_NAME_2).build()).get();
 
         // Schema registration
-        db2.setSchema(
+        db2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Create a String property that make the document exceed the total size limit.
@@ -483,7 +501,7 @@
                 .setSubject("testPut example")
                 .setBody(body)
                 .build();
-        AppSearchBatchResult<String, Void> result = db2.put(
+        AppSearchBatchResult<String, Void> result = db2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email).build()).get();
         assertThat(result.getFailures()).containsKey("id1");
         assertThat(result.getFailures().get("id1").getErrorMessage())
@@ -491,12 +509,42 @@
     }
 
     @Test
-    public void testCapabilities() throws Exception {
+    public void testPutDocuments_emptyBytesAndDocuments() throws Exception {
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = LocalStorage.createSearchSession(
-                new LocalStorage.SearchContext.Builder(context, DB_NAME_2).build()).get();
+        AppSearchSession db = LocalStorage.createSearchSessionAsync(
+                new LocalStorage.SearchContext.Builder(context, DB_NAME_1).build()).get();
+        // Schema registration
+        AppSearchSchema schema = new AppSearchSchema.Builder("testSchema")
+                .addProperty(new AppSearchSchema.BytesPropertyConfig.Builder("bytes")
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                        .build())
+                .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(
+                        "document", AppSearchEmail.SCHEMA_TYPE)
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                        .setShouldIndexNestedProperties(true)
+                        .build())
+                .build();
+        db.setSchemaAsync(new SetSchemaRequest.Builder()
+                .addSchemas(schema, AppSearchEmail.SCHEMA).build()).get();
 
-        assertThat(db2.getFeatures().isFeatureSupported(
-                Features.SEARCH_RESULT_MATCH_INFO_SUBMATCH)).isTrue();
+        // Index a document
+        GenericDocument document = new GenericDocument.Builder<>("namespace", "id1", "testSchema")
+                .setPropertyBytes("bytes")
+                .setPropertyDocument("document")
+                .build();
+
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(db.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(document).build()));
+        assertThat(result.getSuccesses()).containsExactly("id1", null);
+        assertThat(result.getFailures()).isEmpty();
+
+        GetByDocumentIdRequest request = new GetByDocumentIdRequest.Builder("namespace")
+                .addIds("id1")
+                .build();
+        List<GenericDocument> outDocuments = doGet(db, request);
+        assertThat(outDocuments).hasSize(1);
+        GenericDocument outDocument = outDocuments.get(0);
+        assertThat(outDocument.getPropertyBytesArray("bytes")).isEmpty();
+        assertThat(outDocument.getPropertyDocumentArray("document")).isEmpty();
     }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionPlatformCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionPlatformCtsTest.java
index a0cd21a..e5a9f7d 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionPlatformCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionPlatformCtsTest.java
@@ -16,15 +16,27 @@
 // @exportToFramework:skipFile()
 package androidx.appsearch.cts.app;
 
+import static androidx.appsearch.testutil.AppSearchTestUtils.checkIsBatchResultSuccess;
+import static androidx.appsearch.testutil.AppSearchTestUtils.doGet;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assume.assumeTrue;
+
 import android.content.Context;
 import android.os.Build;
 
 import androidx.annotation.NonNull;
+import androidx.appsearch.app.AppSearchBatchResult;
+import androidx.appsearch.app.AppSearchSchema;
 import androidx.appsearch.app.AppSearchSession;
 import androidx.appsearch.app.Features;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.GetByDocumentIdRequest;
+import androidx.appsearch.app.PutDocumentsRequest;
+import androidx.appsearch.app.SetSchemaRequest;
 import androidx.appsearch.platformstorage.PlatformStorage;
+import androidx.appsearch.testutil.AppSearchEmail;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.filters.SdkSuppress;
 
@@ -32,35 +44,102 @@
 
 import org.junit.Test;
 
+import java.util.List;
 import java.util.concurrent.ExecutorService;
 
 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
 public class AppSearchSessionPlatformCtsTest extends AppSearchSessionCtsTestBase {
     @Override
-    protected ListenableFuture<AppSearchSession> createSearchSession(@NonNull String dbName) {
+    protected ListenableFuture<AppSearchSession> createSearchSessionAsync(@NonNull String dbName) {
         Context context = ApplicationProvider.getApplicationContext();
-        return PlatformStorage.createSearchSession(
+        return PlatformStorage.createSearchSessionAsync(
                 new PlatformStorage.SearchContext.Builder(context, dbName).build());
     }
 
     @Override
-    protected ListenableFuture<AppSearchSession> createSearchSession(
+    protected ListenableFuture<AppSearchSession> createSearchSessionAsync(
             @NonNull String dbName, @NonNull ExecutorService executor) {
         Context context = ApplicationProvider.getApplicationContext();
-        return PlatformStorage.createSearchSession(
+        return PlatformStorage.createSearchSessionAsync(
                 new PlatformStorage.SearchContext.Builder(context, dbName)
                         .setWorkerExecutor(executor).build());
     }
 
     @Test
-    public void testCapabilities() throws Exception {
+    public void testFeaturesSupported() throws Exception {
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = PlatformStorage.createSearchSession(
+        AppSearchSession db2 = PlatformStorage.createSearchSessionAsync(
                 new PlatformStorage.SearchContext.Builder(context, DB_NAME_2).build()).get();
-
-        // TODO(b/201316758) Update to reflect support in Android T+ once this feature is synced
-        // over into service-appsearch.
         assertThat(db2.getFeatures().isFeatureSupported(
-                Features.SEARCH_RESULT_MATCH_INFO_SUBMATCH)).isFalse();
+                Features.SEARCH_RESULT_MATCH_INFO_SUBMATCH))
+                .isEqualTo(Build.VERSION.SDK_INT >= 33);
+        assertThat(db2.getFeatures().isFeatureSupported(
+                Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK))
+                .isEqualTo(Build.VERSION.SDK_INT >= 33);
+        assertThat(db2.getFeatures().isFeatureSupported(
+                Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA))
+                .isEqualTo(Build.VERSION.SDK_INT >= 33);
+        assertThat(db2.getFeatures().isFeatureSupported(
+                Features.GLOBAL_SEARCH_SESSION_GET_BY_ID))
+                .isEqualTo(Build.VERSION.SDK_INT >= 33);
+        assertThat(db2.getFeatures().isFeatureSupported(
+                Features.ADD_PERMISSIONS_AND_GET_VISIBILITY))
+                .isEqualTo(Build.VERSION.SDK_INT >= 33);
+    }
+
+    @Test
+    public void testPutDocuments_emptyBytesAndDocuments() throws Exception {
+        Context context = ApplicationProvider.getApplicationContext();
+        AppSearchSession db = PlatformStorage.createSearchSessionAsync(
+                new PlatformStorage.SearchContext.Builder(context, DB_NAME_1).build()).get();
+        // Schema registration
+        AppSearchSchema schema = new AppSearchSchema.Builder("testSchema")
+                .addProperty(new AppSearchSchema.BytesPropertyConfig.Builder("bytes")
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                        .build())
+                .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(
+                        "document", AppSearchEmail.SCHEMA_TYPE)
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                        .setShouldIndexNestedProperties(true)
+                        .build())
+                .build();
+        db.setSchemaAsync(new SetSchemaRequest.Builder()
+                .addSchemas(schema, AppSearchEmail.SCHEMA).build()).get();
+
+        // Index a document
+        GenericDocument document = new GenericDocument.Builder<>("namespace", "id1", "testSchema")
+                .setPropertyBytes("bytes")
+                .setPropertyDocument("document")
+                .build();
+
+        AppSearchBatchResult<String, Void> result = checkIsBatchResultSuccess(db.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(document).build()));
+        assertThat(result.getSuccesses()).containsExactly("id1", null);
+        assertThat(result.getFailures()).isEmpty();
+
+        GetByDocumentIdRequest request = new GetByDocumentIdRequest.Builder("namespace")
+                .addIds("id1")
+                .build();
+        List<GenericDocument> outDocuments = doGet(db, request);
+        assertThat(outDocuments).hasSize(1);
+        GenericDocument outDocument = outDocuments.get(0);
+        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.S
+                || Build.VERSION.SDK_INT == Build.VERSION_CODES.S_V2) {
+            // We fixed b/204677124 in Android T, so in S and S_V2, getByteArray and
+            // getDocumentArray will return null if we set empty properties.
+            assertThat(outDocument.getPropertyBytesArray("bytes")).isNull();
+            assertThat(outDocument.getPropertyDocumentArray("document")).isNull();
+        } else {
+            assertThat(outDocument.getPropertyBytesArray("bytes")).isEmpty();
+            assertThat(outDocument.getPropertyDocumentArray("document")).isEmpty();
+        }
+    }
+
+    @Override
+    @Test
+    public void testPutLargeDocumentBatch() throws Exception {
+        // b/185441119 was fixed in Android T, this test will fail on S_V2 devices and below.
+        assumeTrue(Build.VERSION.SDK_INT >= 33);
+        super.testPutLargeDocumentBatch();
     }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GetSchemaResponseCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GetSchemaResponseCtsTest.java
index 1220731..72faaef 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GetSchemaResponseCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GetSchemaResponseCtsTest.java
@@ -20,12 +20,24 @@
 
 import androidx.appsearch.app.AppSearchSchema;
 import androidx.appsearch.app.GetSchemaResponse;
+import androidx.appsearch.app.PackageIdentifier;
+import androidx.appsearch.app.SetSchemaRequest;
+
+import com.google.common.collect.ImmutableSet;
 
 import org.junit.Test;
 
+import java.util.Arrays;
+
 public class GetSchemaResponseCtsTest {
     @Test
     public void testRebuild() {
+        byte[] sha256cert1 = new byte[32];
+        byte[] sha256cert2 = new byte[32];
+        Arrays.fill(sha256cert1, (byte) 1);
+        Arrays.fill(sha256cert2, (byte) 2);
+        PackageIdentifier packageIdentifier1 = new PackageIdentifier("Email", sha256cert1);
+        PackageIdentifier packageIdentifier2 = new PackageIdentifier("Email", sha256cert2);
         AppSearchSchema schema1 = new AppSearchSchema.Builder("Email1")
                 .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("subject")
                         .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
@@ -44,16 +56,111 @@
                 ).build();
 
         GetSchemaResponse.Builder builder =
-                new GetSchemaResponse.Builder().setVersion(42).addSchema(schema1);
+                new GetSchemaResponse.Builder().setVersion(42).addSchema(schema1)
+                        .addSchemaTypeNotDisplayedBySystem("Email1")
+                        .setSchemaTypeVisibleToPackages("Email1",
+                                ImmutableSet.of(packageIdentifier1))
+                        .setRequiredPermissionsForSchemaTypeVisibility("Email1",
+                                ImmutableSet.of(
+                                        ImmutableSet.of(SetSchemaRequest.READ_SMS,
+                                                SetSchemaRequest.READ_CALENDAR),
+                                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA))
+                        );
 
         GetSchemaResponse original = builder.build();
-        GetSchemaResponse rebuild = builder.setVersion(37).addSchema(schema2).build();
+        GetSchemaResponse rebuild = builder.setVersion(37).addSchema(schema2)
+                .addSchemaTypeNotDisplayedBySystem("Email2")
+                .setSchemaTypeVisibleToPackages("Email2",
+                        ImmutableSet.of(packageIdentifier2))
+                .setRequiredPermissionsForSchemaTypeVisibility("Email2",
+                        ImmutableSet.of(
+                                        ImmutableSet.of(SetSchemaRequest.READ_CONTACTS,
+                                                SetSchemaRequest.READ_EXTERNAL_STORAGE),
+                                        ImmutableSet.of(SetSchemaRequest
+                                                .READ_ASSISTANT_APP_SEARCH_DATA))
+                ).build();
 
         // rebuild won't effect the original object
         assertThat(original.getVersion()).isEqualTo(42);
         assertThat(original.getSchemas()).containsExactly(schema1);
+        assertThat(original.getSchemaTypesNotDisplayedBySystem())
+                .containsExactly("Email1");
+        assertThat(original.getSchemaTypesVisibleToPackages()).hasSize(1);
+        assertThat(original.getSchemaTypesVisibleToPackages().get("Email1"))
+                .containsExactly(packageIdentifier1);
+        assertThat(original.getRequiredPermissionsForSchemaTypeVisibility()).containsExactly(
+                "Email1",
+                ImmutableSet.of(
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS,
+                                SetSchemaRequest.READ_CALENDAR),
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA)));
 
         assertThat(rebuild.getVersion()).isEqualTo(37);
         assertThat(rebuild.getSchemas()).containsExactly(schema1, schema2);
+        assertThat(rebuild.getSchemaTypesNotDisplayedBySystem())
+                .containsExactly("Email1", "Email2");
+        assertThat(rebuild.getSchemaTypesVisibleToPackages()).hasSize(2);
+        assertThat(rebuild.getSchemaTypesVisibleToPackages().get("Email1"))
+                .containsExactly(packageIdentifier1);
+        assertThat(rebuild.getSchemaTypesVisibleToPackages().get("Email2"))
+                .containsExactly(packageIdentifier2);
+        assertThat(rebuild.getRequiredPermissionsForSchemaTypeVisibility()).containsExactly(
+                "Email1",
+                ImmutableSet.of(
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS,
+                                SetSchemaRequest.READ_CALENDAR),
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA)),
+                "Email2",
+                ImmutableSet.of(
+                        ImmutableSet.of(SetSchemaRequest.READ_CONTACTS,
+                                SetSchemaRequest.READ_EXTERNAL_STORAGE),
+                        ImmutableSet.of(SetSchemaRequest
+                                .READ_ASSISTANT_APP_SEARCH_DATA)));
+    }
+
+    @Test
+    public void setVisibility() {
+        byte[] sha256cert1 = new byte[32];
+        byte[] sha256cert2 = new byte[32];
+        Arrays.fill(sha256cert1, (byte) 1);
+        Arrays.fill(sha256cert2, (byte) 2);
+        PackageIdentifier packageIdentifier1 = new PackageIdentifier("Email", sha256cert1);
+        PackageIdentifier packageIdentifier2 = new PackageIdentifier("Email", sha256cert2);
+
+        GetSchemaResponse getSchemaResponse =
+                new GetSchemaResponse.Builder().setVersion(42)
+                        .addSchemaTypeNotDisplayedBySystem("Email")
+                        .addSchemaTypeNotDisplayedBySystem("Text")
+                        .setSchemaTypeVisibleToPackages("Email",
+                                ImmutableSet.of(packageIdentifier1, packageIdentifier2))
+                        .setRequiredPermissionsForSchemaTypeVisibility("Email",
+                                ImmutableSet.of(
+                                                ImmutableSet.of(SetSchemaRequest.READ_CONTACTS,
+                                                        SetSchemaRequest.READ_EXTERNAL_STORAGE),
+                                                ImmutableSet.of(SetSchemaRequest
+                                                        .READ_ASSISTANT_APP_SEARCH_DATA)))
+                        .build();
+
+        assertThat(getSchemaResponse.getSchemaTypesNotDisplayedBySystem())
+                .containsExactly("Email", "Text");
+        assertThat(getSchemaResponse.getSchemaTypesVisibleToPackages()).hasSize(1);
+        assertThat(getSchemaResponse.getSchemaTypesVisibleToPackages().get("Email"))
+                .containsExactly(packageIdentifier1, packageIdentifier2);
+        assertThat(getSchemaResponse.getRequiredPermissionsForSchemaTypeVisibility().get("Email"))
+                .containsExactlyElementsIn(ImmutableSet.of(
+                        ImmutableSet.of(SetSchemaRequest.READ_CONTACTS,
+                                SetSchemaRequest.READ_EXTERNAL_STORAGE),
+                        ImmutableSet.of(SetSchemaRequest
+                                .READ_ASSISTANT_APP_SEARCH_DATA)));
+    }
+
+    @Test
+    public void getEmptyVisibility() {
+        GetSchemaResponse getSchemaResponse =
+                new GetSchemaResponse.Builder().setVersion(42)
+                        .build();
+        assertThat(getSchemaResponse.getSchemaTypesNotDisplayedBySystem()).isEmpty();
+        assertThat(getSchemaResponse.getSchemaTypesVisibleToPackages()).isEmpty();
+        assertThat(getSchemaResponse.getRequiredPermissionsForSchemaTypeVisibility()).isEmpty();
     }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionCtsTestBase.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionCtsTestBase.java
index 1e03d4e..3c9086b 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionCtsTestBase.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionCtsTestBase.java
@@ -28,13 +28,17 @@
 import android.content.Context;
 
 import androidx.annotation.NonNull;
+import androidx.appsearch.app.AppSearchBatchResult;
 import androidx.appsearch.app.AppSearchResult;
 import androidx.appsearch.app.AppSearchSchema;
 import androidx.appsearch.app.AppSearchSchema.PropertyConfig;
 import androidx.appsearch.app.AppSearchSession;
 import androidx.appsearch.app.Features;
 import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.GetByDocumentIdRequest;
+import androidx.appsearch.app.GetSchemaResponse;
 import androidx.appsearch.app.GlobalSearchSession;
+import androidx.appsearch.app.Migrator;
 import androidx.appsearch.app.PutDocumentsRequest;
 import androidx.appsearch.app.RemoveByDocumentIdRequest;
 import androidx.appsearch.app.ReportSystemUsageRequest;
@@ -45,11 +49,13 @@
 import androidx.appsearch.exceptions.AppSearchException;
 import androidx.appsearch.observer.DocumentChangeInfo;
 import androidx.appsearch.observer.ObserverSpec;
+import androidx.appsearch.observer.SchemaChangeInfo;
 import androidx.appsearch.testutil.AppSearchEmail;
 import androidx.appsearch.testutil.TestObserverCallback;
 import androidx.test.core.app.ApplicationProvider;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.util.concurrent.ListenableFuture;
 
 import org.junit.After;
@@ -75,21 +81,21 @@
 
     protected GlobalSearchSession mGlobalSearchSession;
 
-    protected abstract ListenableFuture<AppSearchSession> createSearchSession(
+    protected abstract ListenableFuture<AppSearchSession> createSearchSessionAsync(
             @NonNull String dbName);
 
-    protected abstract ListenableFuture<GlobalSearchSession> createGlobalSearchSession();
+    protected abstract ListenableFuture<GlobalSearchSession> createGlobalSearchSessionAsync();
 
     @Before
     public void setUp() throws Exception {
-        mDb1 = createSearchSession(DB_NAME_1).get();
-        mDb2 = createSearchSession(DB_NAME_2).get();
+        mDb1 = createSearchSessionAsync(DB_NAME_1).get();
+        mDb2 = createSearchSessionAsync(DB_NAME_2).get();
 
         // Cleanup whatever documents may still exist in these databases. This is needed in
         // addition to tearDown in case a test exited without completing properly.
         cleanup();
 
-        mGlobalSearchSession = createGlobalSearchSession().get();
+        mGlobalSearchSession = createGlobalSearchSessionAsync().get();
     }
 
     @After
@@ -99,9 +105,9 @@
     }
 
     private void cleanup() throws Exception {
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().setForceOverride(true).build()).get();
-        mDb2.setSchema(
+        mDb2.setSchemaAsync(
                 new SetSchemaRequest.Builder().setForceOverride(true).build()).get();
     }
 
@@ -128,6 +134,61 @@
     }
 
     @Test
+    public void testGlobalGetById() throws Exception {
+        assumeTrue(mGlobalSearchSession.getFeatures().isFeatureSupported(
+                Features.GLOBAL_SEARCH_SESSION_GET_BY_ID));
+        SearchSpec exactSearchSpec = new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .build();
+
+        // Schema registration
+        mDb1.setSchemaAsync(
+                new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
+
+        AppSearchBatchResult<String, GenericDocument> nonExistent =
+                mGlobalSearchSession.getByDocumentIdAsync(mContext.getPackageName(), DB_NAME_1,
+                        new GetByDocumentIdRequest.Builder("namespace").addIds("id1")
+                                .build()).get();
+
+        assertThat(nonExistent.isSuccess()).isFalse();
+        assertThat(nonExistent.getSuccesses()).isEmpty();
+        assertThat(nonExistent.getFailures()).containsKey("id1");
+        assertThat(nonExistent.getFailures().get("id1").getResultCode())
+                .isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
+
+        // Index a document
+        AppSearchEmail inEmail =
+                new AppSearchEmail.Builder("namespace", "id1")
+                        .setFrom("[email protected]")
+                        .setTo("[email protected]", "[email protected]")
+                        .setSubject("testPut example")
+                        .setBody("This is the body of the testPut email")
+                        .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail).build()));
+
+        // Query for the document
+        AppSearchBatchResult<String, GenericDocument> afterPutDocuments =
+                mGlobalSearchSession.getByDocumentIdAsync(mContext.getPackageName(), DB_NAME_1,
+                        new GetByDocumentIdRequest.Builder("namespace").addIds("id1")
+                                .build()).get();
+        assertThat(afterPutDocuments.getSuccesses()).containsExactly("id1", inEmail);
+    }
+
+    @Test
+    public void testGlobalGetById_nonExistentPackage() throws Exception {
+        assumeTrue(mGlobalSearchSession.getFeatures().isFeatureSupported(
+                Features.GLOBAL_SEARCH_SESSION_GET_BY_ID));
+        AppSearchBatchResult<String, GenericDocument> fakePackage =
+                mGlobalSearchSession.getByDocumentIdAsync("fake", DB_NAME_1,
+                        new GetByDocumentIdRequest.Builder("namespace").addIds("id1")
+                                .build()).get();
+        assertThat(fakePackage.getFailures()).hasSize(1);
+        assertThat(fakePackage.getFailures().get("id1").getResultCode())
+                .isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
+    }
+
+    @Test
     public void testGlobalQuery_oneInstance() throws Exception {
         // Snapshot what documents may already exist on the device.
         SearchSpec exactSearchSpec = new SearchSpec.Builder()
@@ -138,7 +199,7 @@
                 exactSearchSpec);
 
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index a document
@@ -149,7 +210,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail).build()));
 
         // Query for the document
@@ -173,9 +234,9 @@
         List<GenericDocument> beforeBodyDocuments = snapshotResults("body", exactSearchSpec);
 
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
-        mDb2.setSchema(
+        mDb2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index a document to instance 1.
@@ -186,7 +247,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1).build()));
 
         // Index a document to instance 2.
@@ -197,7 +258,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail2).build()));
 
         // Query across all instances
@@ -215,7 +276,7 @@
         List<GenericDocument> beforeBodyDocuments = snapshotResults("body", exactSearchSpec);
 
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
         List<AppSearchEmail> emailList = new ArrayList<>();
         PutDocumentsRequest.Builder putDocumentsRequestBuilder = new PutDocumentsRequest.Builder();
@@ -232,7 +293,7 @@
             emailList.add(inEmail);
             putDocumentsRequestBuilder.addGenericDocuments(inEmail);
         }
-        checkIsBatchResultSuccess(mDb1.put(putDocumentsRequestBuilder.build()));
+        checkIsBatchResultSuccess(mDb1.putAsync(putDocumentsRequestBuilder.build()));
 
         // Set number of results per page is 7.
         int pageSize = 7;
@@ -248,7 +309,7 @@
 
         // keep loading next page until it's empty.
         do {
-            results = searchResults.getNextPage().get();
+            results = searchResults.getNextPageAsync().get();
             ++pageNumber;
             for (SearchResult result : results) {
                 documents.add(result.getGenericDocument());
@@ -293,19 +354,19 @@
                 ).build();
 
         // db1 has both "Generic" and "builtin:Email"
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(genericSchema).addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // db2 only has "builtin:Email"
-        mDb2.setSchema(
+        mDb2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index a generic document into db1
         GenericDocument genericDocument = new GenericDocument.Builder<>("namespace", "id2",
                 "Generic")
                 .setPropertyString("foo", "body").build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(genericDocument).build()));
 
@@ -318,9 +379,9 @@
                         .build();
 
         // Put the email in both databases
-        checkIsBatchResultSuccess((mDb1.put(
+        checkIsBatchResultSuccess((mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email).build())));
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(email).build()));
 
         // Query for all documents across types
@@ -352,9 +413,9 @@
                 exactNamespace1SearchSpec);
 
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
-        mDb2.setSchema(
+        mDb2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index two documents
@@ -365,7 +426,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(document1).build()));
 
@@ -376,7 +437,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(document2).build()));
 
         // Query for all namespaces
@@ -410,9 +471,9 @@
                 testPackageSearchSpec);
 
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
-        mDb2.setSchema(
+        mDb2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index two documents
@@ -423,7 +484,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(document1).build()));
 
@@ -434,7 +495,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(document2).build()));
 
         // Query in some other package
@@ -454,11 +515,11 @@
     @Test
     public void testGlobalQuery_projectionTwoInstances() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .build()).get();
-        mDb2.setSchema(
+        mDb2.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .build()).get();
@@ -472,7 +533,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1).build()));
 
@@ -484,7 +545,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email2).build()));
 
@@ -516,11 +577,11 @@
     @Test
     public void testGlobalQuery_projectionEmptyTwoInstances() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .build()).get();
-        mDb2.setSchema(
+        mDb2.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .build()).get();
@@ -534,7 +595,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1).build()));
 
@@ -546,7 +607,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email2).build()));
 
@@ -573,11 +634,11 @@
     @Test
     public void testGlobalQuery_projectionNonExistentTypeTwoInstances() throws Exception {
         // Schema registration
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .build()).get();
-        mDb2.setSchema(
+        mDb2.setSchemaAsync(
                 new SetSchemaRequest.Builder()
                         .addSchemas(AppSearchEmail.SCHEMA)
                         .build()).get();
@@ -591,7 +652,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1).build()));
 
@@ -603,7 +664,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email2).build()));
 
@@ -636,9 +697,9 @@
     @Test
     public void testQuery_ResultGroupingLimits() throws Exception {
         // Schema registration
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
-        mDb2.setSchema(new SetSchemaRequest.Builder()
+        mDb2.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index one document in 'namespace1' and one document in 'namespace2' into db1.
@@ -649,7 +710,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1).build()));
         AppSearchEmail inEmail2 =
                 new AppSearchEmail.Builder("namespace2", "id2")
@@ -658,7 +719,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb1.put(
+        checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail2).build()));
 
         // Index one document in 'namespace1' and one document in 'namespace2' into db2.
@@ -669,7 +730,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail3).build()));
         AppSearchEmail inEmail4 =
                 new AppSearchEmail.Builder("namespace2", "id4")
@@ -678,7 +739,7 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(mDb2.put(
+        checkIsBatchResultSuccess(mDb2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail4).build()));
 
         // Query with per package result grouping. Only the last document 'email4' should be
@@ -716,7 +777,7 @@
     @Test
     public void testReportSystemUsage_ForbiddenFromNonSystem() throws Exception {
         // Index a document
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
         AppSearchEmail email1 =
                 new AppSearchEmail.Builder("namespace", "id1")
@@ -727,7 +788,8 @@
                         .setBody("This is the body of the testPut email")
                         .build();
         checkIsBatchResultSuccess(
-                mDb1.put(new PutDocumentsRequest.Builder().addGenericDocuments(email1).build()));
+                mDb1.putAsync(new PutDocumentsRequest.Builder()
+                        .addGenericDocuments(email1).build()));
 
         // Query
         List<SearchResult> page;
@@ -735,13 +797,13 @@
                 .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
                 .addFilterSchemas(AppSearchEmail.SCHEMA_TYPE)
                 .build())) {
-            page = results.getNextPage().get();
+            page = results.getNextPageAsync().get();
         }
         assertThat(page).isNotEmpty();
         SearchResult firstResult = page.get(0);
 
         ExecutionException exception = assertThrows(
-                ExecutionException.class, () -> mGlobalSearchSession.reportSystemUsage(
+                ExecutionException.class, () -> mGlobalSearchSession.reportSystemUsageAsync(
                         new ReportSystemUsageRequest.Builder(
                                 firstResult.getPackageName(),
                                 firstResult.getDatabaseName(),
@@ -758,56 +820,63 @@
     @Test
     public void testAddObserver_notSupported() {
         assumeFalse(mGlobalSearchSession.getFeatures()
-                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER));
+                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK));
         assertThrows(
                 UnsupportedOperationException.class,
-                () -> mGlobalSearchSession.addObserver(
+                () -> mGlobalSearchSession.registerObserverCallback(
                         mContext.getPackageName(),
                         new ObserverSpec.Builder().build(),
                         EXECUTOR,
                         new TestObserverCallback()));
         assertThrows(
                 UnsupportedOperationException.class,
-                () -> mGlobalSearchSession.removeObserver(
+                () -> mGlobalSearchSession.unregisterObserverCallback(
                         mContext.getPackageName(), new TestObserverCallback()));
     }
 
     @Test
     public void testAddObserver() throws Exception {
         assumeTrue(mGlobalSearchSession.getFeatures()
-                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER));
+                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK));
 
         TestObserverCallback observer = new TestObserverCallback();
 
         // Register observer. Note: the type does NOT exist yet!
-        mGlobalSearchSession.addObserver(
+        mGlobalSearchSession.registerObserverCallback(
                 mContext.getPackageName(),
                 new ObserverSpec.Builder().addFilterSchemas(AppSearchEmail.SCHEMA_TYPE).build(),
                 EXECUTOR,
                 observer);
 
         // Index a document
-        mDb1.setSchema(
+        mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
         AppSearchEmail email1 = new AppSearchEmail.Builder("namespace", "id1").build();
         checkIsBatchResultSuccess(
-                mDb1.put(new PutDocumentsRequest.Builder().addGenericDocuments(email1).build()));
+                mDb1.putAsync(new PutDocumentsRequest.Builder()
+                        .addGenericDocuments(email1).build()));
 
         // Make sure the notification was received.
-        observer.waitForNotificationCount(1);
-        assertThat(observer.getSchemaChanges()).isEmpty();
+        observer.waitForNotificationCount(2);
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(),
+                        DB_NAME_1,
+                        /*changedSchemaNames=*/ImmutableSet.of(AppSearchEmail.SCHEMA_TYPE)));
         assertThat(observer.getDocumentChanges()).containsExactly(
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE));
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1"))
+        );
     }
 
     @Test
     public void testRegisterObserver_MultiType() throws Exception {
         assumeTrue(mGlobalSearchSession.getFeatures()
-                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER));
+                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK));
 
         TestObserverCallback unfilteredObserver = new TestObserverCallback();
         TestObserverCallback emailObserver = new TestObserverCallback();
@@ -816,18 +885,18 @@
         AppSearchSchema giftSchema = new AppSearchSchema.Builder("Gift")
                 .addProperty(new AppSearchSchema.DoublePropertyConfig.Builder("price").build())
                 .build();
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA, giftSchema).build()).get();
-        mDb2.setSchema(new SetSchemaRequest.Builder()
+        mDb2.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Register two observers. One has no filters, the other filters on email.
-        mGlobalSearchSession.addObserver(
+        mGlobalSearchSession.registerObserverCallback(
                 mContext.getPackageName(),
                 new ObserverSpec.Builder().build(),
                 EXECUTOR,
                 unfilteredObserver);
-        mGlobalSearchSession.addObserver(
+        mGlobalSearchSession.registerObserverCallback(
                 mContext.getPackageName(),
                 new ObserverSpec.Builder().addFilterSchemas(AppSearchEmail.SCHEMA_TYPE).build(),
                 EXECUTOR,
@@ -845,14 +914,17 @@
                 "namespace2", "id2", "Gift").build();
 
         checkIsBatchResultSuccess(
-                mDb1.put(new PutDocumentsRequest.Builder().addGenericDocuments(email1).build()));
+                mDb1.putAsync(new PutDocumentsRequest.Builder()
+                        .addGenericDocuments(email1).build()));
         checkIsBatchResultSuccess(
-                mDb1.put(new PutDocumentsRequest.Builder()
+                mDb1.putAsync(new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1, gift1).build()));
         checkIsBatchResultSuccess(
-                mDb2.put(new PutDocumentsRequest.Builder().addGenericDocuments(email1).build()));
+                mDb2.putAsync(new PutDocumentsRequest.Builder()
+                        .addGenericDocuments(email1).build()));
         checkIsBatchResultSuccess(
-                mDb1.put(new PutDocumentsRequest.Builder().addGenericDocuments(gift1).build()));
+                mDb1.putAsync(new PutDocumentsRequest.Builder()
+                        .addGenericDocuments(gift1).build()));
 
         // Make sure the notification was received.
         unfilteredObserver.waitForNotificationCount(5);
@@ -864,27 +936,32 @@
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace2",
-                        "Gift"),
+                        "Gift",
+                        /*changedDocumentIds=*/ImmutableSet.of("id2")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_2,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace2",
-                        "Gift")
+                        "Gift",
+                        /*changedDocumentIds=*/ImmutableSet.of("id2"))
         );
 
         // Check the filtered observer
@@ -894,24 +971,27 @@
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_2,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE)
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1"))
         );
     }
 
     @Test
     public void testRegisterObserver_removeById() throws Exception {
         assumeTrue(mGlobalSearchSession.getFeatures()
-                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER));
+                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK));
 
         TestObserverCallback unfilteredObserver = new TestObserverCallback();
         TestObserverCallback emailObserver = new TestObserverCallback();
@@ -920,14 +1000,14 @@
         AppSearchSchema giftSchema = new AppSearchSchema.Builder("Gift")
                 .addProperty(new AppSearchSchema.DoublePropertyConfig.Builder("price").build())
                 .build();
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA, giftSchema).build()).get();
-        mDb2.setSchema(new SetSchemaRequest.Builder()
+        mDb2.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA, giftSchema).build()).get();
 
         // Register two observers. One, registered later, has no filters. The other, registered
         // now, filters on email.
-        mGlobalSearchSession.addObserver(
+        mGlobalSearchSession.registerObserverCallback(
                 mContext.getPackageName(),
                 new ObserverSpec.Builder().addFilterSchemas(AppSearchEmail.SCHEMA_TYPE).build(),
                 EXECUTOR,
@@ -945,27 +1025,29 @@
                 "namespace2", "id2", "Gift").build();
 
         checkIsBatchResultSuccess(
-                mDb1.put(new PutDocumentsRequest.Builder().addGenericDocuments(email1).build()));
+                mDb1.putAsync(new PutDocumentsRequest.Builder()
+                        .addGenericDocuments(email1).build()));
         checkIsBatchResultSuccess(
-                mDb1.put(new PutDocumentsRequest.Builder()
+                mDb1.putAsync(new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1, gift1).build()));
         checkIsBatchResultSuccess(
-                mDb2.put(new PutDocumentsRequest.Builder()
+                mDb2.putAsync(new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1, gift1).build()));
         checkIsBatchResultSuccess(
-                mDb1.put(new PutDocumentsRequest.Builder().addGenericDocuments(gift1).build()));
+                mDb1.putAsync(new PutDocumentsRequest.Builder()
+                        .addGenericDocuments(gift1).build()));
 
         // Register the second observer
-        mGlobalSearchSession.addObserver(
+        mGlobalSearchSession.registerObserverCallback(
                 mContext.getPackageName(),
                 new ObserverSpec.Builder().build(),
                 EXECUTOR,
                 unfilteredObserver);
 
         // Remove some of the documents.
-        checkIsBatchResultSuccess(mDb1.remove(
+        checkIsBatchResultSuccess(mDb1.removeAsync(
                 new RemoveByDocumentIdRequest.Builder("namespace").addIds("id1").build()));
-        checkIsBatchResultSuccess(mDb2.remove(
+        checkIsBatchResultSuccess(mDb2.removeAsync(
                 new RemoveByDocumentIdRequest.Builder("namespace2").addIds("id2").build()));
 
         // Make sure the notification was received. emailObserver should have seen:
@@ -981,22 +1063,26 @@
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_2,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE)
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1"))
         );
 
         // Check unfilteredObserver
@@ -1006,19 +1092,21 @@
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_2,
                         "namespace2",
-                        "Gift")
+                        "Gift",
+                        /*changedDocumentIds=*/ImmutableSet.of("id2"))
         );
     }
 
     @Test
     public void testRegisterObserver_removeByQuery() throws Exception {
         assumeTrue(mGlobalSearchSession.getFeatures()
-                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER));
+                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK));
 
         TestObserverCallback unfilteredObserver = new TestObserverCallback();
         TestObserverCallback emailObserver = new TestObserverCallback();
@@ -1027,9 +1115,9 @@
         AppSearchSchema giftSchema = new AppSearchSchema.Builder("Gift")
                 .addProperty(new AppSearchSchema.DoublePropertyConfig.Builder("price").build())
                 .build();
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA, giftSchema).build()).get();
-        mDb2.setSchema(new SetSchemaRequest.Builder()
+        mDb2.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA, giftSchema).build()).get();
 
         // Index some documents
@@ -1040,19 +1128,19 @@
                 "namespace2", "id3", "Gift").build();
 
         checkIsBatchResultSuccess(
-                mDb1.put(new PutDocumentsRequest.Builder()
+                mDb1.putAsync(new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1, email2, gift1).build()));
         checkIsBatchResultSuccess(
-                mDb2.put(new PutDocumentsRequest.Builder().addGenericDocuments(
+                mDb2.putAsync(new PutDocumentsRequest.Builder().addGenericDocuments(
                         email1, email2, gift1).build()));
 
         // Register observers
-        mGlobalSearchSession.addObserver(
+        mGlobalSearchSession.registerObserverCallback(
                 mContext.getPackageName(),
                 new ObserverSpec.Builder().build(),
                 EXECUTOR,
                 unfilteredObserver);
-        mGlobalSearchSession.addObserver(
+        mGlobalSearchSession.registerObserverCallback(
                 mContext.getPackageName(),
                 new ObserverSpec.Builder().addFilterSchemas(AppSearchEmail.SCHEMA_TYPE).build(),
                 EXECUTOR,
@@ -1065,20 +1153,16 @@
         assertThat(emailObserver.getDocumentChanges()).isEmpty();
 
         // Remove "cat" emails in db1 and all types in db2
-        mDb1.remove(
-                "cat",
-                new SearchSpec.Builder().addFilterSchemas(AppSearchEmail.SCHEMA_TYPE).build())
+        mDb1.removeAsync("cat",
+                        new SearchSpec.Builder()
+                                .addFilterSchemas(AppSearchEmail.SCHEMA_TYPE).build())
                 .get();
-        mDb2.remove("", new SearchSpec.Builder().build()).get();
+        mDb2.removeAsync("", new SearchSpec.Builder().build()).get();
 
         // Make sure the notification was received. UnfilteredObserver should have seen:
         //   -db1:id2, -db2:id1, -db2:id2, -db2:id3
         // emailObserver should have seen:
         //   -db1:id2, -db2:id1, -db2:id2
-        // TODO(b/193494000): Notifications are currently grouped by
-        //  (package, database, namespace, schema). This causes -db2:id1 and -db2:id2 to be combined
-        //  into one notification. Once notifications have IDs, we need to check to make sure all
-        //  the individual IDs are reported in the combined notification.
         unfilteredObserver.waitForNotificationCount(3);
         emailObserver.waitForNotificationCount(2);
 
@@ -1088,17 +1172,20 @@
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id2")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_2,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1", "id2")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_2,
                         "namespace2",
-                        "Gift")
+                        "Gift",
+                        /*changedDocumentIds=*/ImmutableSet.of("id3"))
         );
 
         // Check emailObserver
@@ -1108,19 +1195,21 @@
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id2")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_2,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE)
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1", "id2"))
         );
     }
 
     @Test
     public void testRegisterObserver_sameCallback_differentSpecs() throws Exception {
         assumeTrue(mGlobalSearchSession.getFeatures()
-                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER));
+                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK));
 
         TestObserverCallback observer = new TestObserverCallback();
 
@@ -1128,16 +1217,16 @@
         AppSearchSchema giftSchema = new AppSearchSchema.Builder("Gift")
                 .addProperty(new AppSearchSchema.DoublePropertyConfig.Builder("price").build())
                 .build();
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA, giftSchema).build()).get();
 
         // Register the same observer twice: once for gift, once for email
-        mGlobalSearchSession.addObserver(
+        mGlobalSearchSession.registerObserverCallback(
                 mContext.getPackageName(),
                 new ObserverSpec.Builder().addFilterSchemas("Gift").build(),
                 EXECUTOR,
                 observer);
-        mGlobalSearchSession.addObserver(
+        mGlobalSearchSession.registerObserverCallback(
                 mContext.getPackageName(),
                 new ObserverSpec.Builder().addFilterSchemas(AppSearchEmail.SCHEMA_TYPE).build(),
                 EXECUTOR,
@@ -1149,7 +1238,7 @@
                 "namespace2", "id3", "Gift").build();
 
         checkIsBatchResultSuccess(
-                mDb1.put(new PutDocumentsRequest.Builder()
+                mDb1.putAsync(new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1, gift1).build()));
 
         // Make sure the same observer received both values
@@ -1160,19 +1249,21 @@
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace2",
-                        "Gift")
+                        "Gift",
+                        /*changedDocumentIds=*/ImmutableSet.of("id3"))
         );
     }
 
     @Test
     public void testRemoveObserver() throws Exception {
         assumeTrue(mGlobalSearchSession.getFeatures()
-                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER));
+                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK));
 
         TestObserverCallback temporaryObserver = new TestObserverCallback();
         TestObserverCallback permanentObserver = new TestObserverCallback();
@@ -1181,24 +1272,24 @@
         AppSearchSchema giftSchema = new AppSearchSchema.Builder("Gift")
                 .addProperty(new AppSearchSchema.DoublePropertyConfig.Builder("price").build())
                 .build();
-        mDb1.setSchema(new SetSchemaRequest.Builder()
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA, giftSchema).build()).get();
-        mDb2.setSchema(new SetSchemaRequest.Builder()
+        mDb2.setSchemaAsync(new SetSchemaRequest.Builder()
                 .addSchemas(AppSearchEmail.SCHEMA, giftSchema).build()).get();
 
         // Register both observers. temporaryObserver is registered twice to ensure both instances
         // get removed.
-        mGlobalSearchSession.addObserver(
+        mGlobalSearchSession.registerObserverCallback(
                 mContext.getPackageName(),
                 new ObserverSpec.Builder().addFilterSchemas(AppSearchEmail.SCHEMA_TYPE).build(),
                 EXECUTOR,
                 temporaryObserver);
-        mGlobalSearchSession.addObserver(
+        mGlobalSearchSession.registerObserverCallback(
                 mContext.getPackageName(),
                 new ObserverSpec.Builder().addFilterSchemas("Gift").build(),
                 EXECUTOR,
                 temporaryObserver);
-        mGlobalSearchSession.addObserver(
+        mGlobalSearchSession.registerObserverCallback(
                 mContext.getPackageName(),
                 new ObserverSpec.Builder().build(),
                 EXECUTOR,
@@ -1220,7 +1311,7 @@
                 "namespace3", "id4", "Gift").build();
 
         checkIsBatchResultSuccess(
-                mDb1.put(new PutDocumentsRequest.Builder()
+                mDb1.putAsync(new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email1, gift1).build()));
 
         // Make sure the notifications were received.
@@ -1232,12 +1323,14 @@
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace2",
-                        "Gift"));
+                        "Gift",
+                        /*changedDocumentIds=*/ImmutableSet.of("id3")));
         assertThat(temporaryObserver.getSchemaChanges()).isEmpty();
         assertThat(temporaryObserver.getDocumentChanges())
                 .containsExactlyElementsIn(expectedChangesOrig);
@@ -1246,11 +1339,12 @@
                 .containsExactlyElementsIn(expectedChangesOrig);
 
         // Unregister temporaryObserver
-        mGlobalSearchSession.removeObserver(mContext.getPackageName(), temporaryObserver);
+        mGlobalSearchSession.unregisterObserverCallback(
+                mContext.getPackageName(), temporaryObserver);
 
         // Index some more documents
         checkIsBatchResultSuccess(
-                mDb1.put(new PutDocumentsRequest.Builder()
+                mDb1.putAsync(new PutDocumentsRequest.Builder()
                         .addGenericDocuments(email2, gift2).build()));
 
         // Only the permanent observer should have received this
@@ -1263,25 +1357,462 @@
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id1")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace2",
-                        "Gift"),
+                        "Gift",
+                        /*changedDocumentIds=*/ImmutableSet.of("id3")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace",
-                        AppSearchEmail.SCHEMA_TYPE),
+                        AppSearchEmail.SCHEMA_TYPE,
+                        /*changedDocumentIds=*/ImmutableSet.of("id2")),
                 new DocumentChangeInfo(
                         mContext.getPackageName(),
                         DB_NAME_1,
                         "namespace3",
-                        "Gift")
+                        "Gift",
+                        /*changedDocumentIds=*/ImmutableSet.of("id4"))
         );
         assertThat(temporaryObserver.getSchemaChanges()).isEmpty();
         assertThat(temporaryObserver.getDocumentChanges())
                 .containsExactlyElementsIn(expectedChangesOrig);
     }
+
+    @Test
+    public void testGlobalGetSchema() throws Exception {
+        assumeTrue(mGlobalSearchSession.getFeatures()
+                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA));
+
+        // One schema should be set with global access and the other should be set with local
+        // access.
+        mDb1.setSchemaAsync(
+                new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
+        mDb2.setSchemaAsync(
+                new SetSchemaRequest.Builder().addSchemas(
+                        AppSearchEmail.SCHEMA).setSchemaTypeDisplayedBySystem(
+                        AppSearchEmail.SCHEMA_TYPE, /*displayed=*/false).build()).get();
+
+        GetSchemaResponse response = mGlobalSearchSession.getSchemaAsync(mContext.getPackageName(),
+                DB_NAME_1).get();
+        assertThat(response.getSchemas()).containsExactly(AppSearchEmail.SCHEMA);
+
+        response = mGlobalSearchSession.getSchemaAsync(mContext.getPackageName(), DB_NAME_2).get();
+        assertThat(response.getSchemas()).containsExactly(AppSearchEmail.SCHEMA);
+
+        // A request for a db that doesn't exist should return a response with no schemas.
+        response = mGlobalSearchSession.getSchemaAsync(
+                mContext.getPackageName(), "NonexistentDb").get();
+        assertThat(response.getSchemas()).isEmpty();
+    }
+
+    @Test
+    public void testGlobalGetSchema_notSupported() throws Exception {
+        assumeFalse(mGlobalSearchSession.getFeatures()
+                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA));
+
+        // One schema should be set with global access and the other should be set with local
+        // access.
+        mDb1.setSchemaAsync(
+                new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
+
+        UnsupportedOperationException e = assertThrows(UnsupportedOperationException.class,
+                () -> mGlobalSearchSession.getSchemaAsync(mContext.getPackageName(), DB_NAME_1));
+        assertThat(e).hasMessageThat().isEqualTo(Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA
+                + " is not supported on this AppSearch implementation.");
+    }
+
+    @Test
+    public void testGlobalGetByDocumentId_notSupported() throws Exception {
+        assumeFalse(mGlobalSearchSession.getFeatures()
+                .isFeatureSupported(Features.GLOBAL_SEARCH_SESSION_GET_BY_ID));
+
+        Context context = ApplicationProvider.getApplicationContext();
+
+        UnsupportedOperationException e = assertThrows(UnsupportedOperationException.class,
+                () -> mGlobalSearchSession.getByDocumentIdAsync(context.getPackageName(), DB_NAME_1,
+                        new GetByDocumentIdRequest.Builder("namespace")
+                                .addIds("id").build()));
+
+        assertThat(e).hasMessageThat().isEqualTo(Features.GLOBAL_SEARCH_SESSION_GET_BY_ID
+                + " is not supported on this AppSearch implementation.");
+    }
+
+    @Test
+    public void testAddObserver_schemaChange_added() throws Exception {
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mGlobalSearchSession.registerObserverCallback(
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                EXECUTOR,
+                observer);
+
+        // Add a schema type
+        assertThat(observer.getSchemaChanges()).isEmpty();
+        assertThat(observer.getDocumentChanges()).isEmpty();
+        mDb1.setSchemaAsync(
+                        new SetSchemaRequest.Builder()
+                                .addSchemas(new AppSearchSchema.Builder("Type1").build())
+                                .build())
+                .get();
+
+        observer.waitForNotificationCount(1);
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(),
+                        DB_NAME_1,
+                        ImmutableSet.of("Type1")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+
+        // Add two more schema types without touching the existing one
+        observer.clear();
+        mDb1.setSchemaAsync(
+                        new SetSchemaRequest.Builder()
+                                .addSchemas(
+                                        new AppSearchSchema.Builder("Type1").build(),
+                                        new AppSearchSchema.Builder("Type2").build(),
+                                        new AppSearchSchema.Builder("Type3").build())
+                                .build())
+                .get();
+
+        observer.waitForNotificationCount(1);
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), DB_NAME_1, ImmutableSet.of("Type2", "Type3")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testAddObserver_schemaChange_removed() throws Exception {
+        // Add a schema type
+        mDb1.setSchemaAsync(
+                        new SetSchemaRequest.Builder()
+                                .addSchemas(
+                                        new AppSearchSchema.Builder("Type1").build(),
+                                        new AppSearchSchema.Builder("Type2").build())
+                                .build())
+                .get();
+
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mGlobalSearchSession.registerObserverCallback(
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                EXECUTOR,
+                observer);
+
+        // Remove Type2
+        mDb1.setSchemaAsync(
+                        new SetSchemaRequest.Builder()
+                                .addSchemas(new AppSearchSchema.Builder("Type1").build())
+                                .setForceOverride(true)
+                                .build())
+                .get();
+
+        observer.waitForNotificationCount(1);
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), DB_NAME_1, ImmutableSet.of("Type2")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testAddObserver_schemaChange_contents() throws Exception {
+        // Add a schema
+        mDb1.setSchemaAsync(
+            new SetSchemaRequest.Builder()
+                    .addSchemas(
+                            new AppSearchSchema.Builder("Type1").build(),
+                            new AppSearchSchema.Builder("Type2")
+                                    .addProperty(
+                                            new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                                    "booleanProp")
+                                                    .setCardinality(
+                                                            PropertyConfig.CARDINALITY_REQUIRED)
+                                                    .build())
+                                    .build())
+                    .build())
+            .get();
+
+        // Register an observer
+        TestObserverCallback observer = new TestObserverCallback();
+        mGlobalSearchSession.registerObserverCallback(
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().build(),
+                EXECUTOR,
+                observer);
+
+        // Update the schema, but don't make any actual changes
+        mDb1.setSchemaAsync(
+            new SetSchemaRequest.Builder()
+                    .addSchemas(
+                            new AppSearchSchema.Builder("Type1").build(),
+                            new AppSearchSchema.Builder("Type2")
+                                    .addProperty(
+                                            new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                                    "booleanProp")
+                                                    .setCardinality(
+                                                            PropertyConfig.CARDINALITY_REQUIRED)
+                                                    .build())
+                                    .build())
+                    .build())
+            .get();
+
+        // Now update the schema again, but this time actually make a change (cardinality of the
+        // property)
+        mDb1.setSchemaAsync(
+            new SetSchemaRequest.Builder()
+                    .addSchemas(
+                            new AppSearchSchema.Builder("Type1").build(),
+                            new AppSearchSchema.Builder("Type2")
+                                    .addProperty(
+                                            new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                                    "booleanProp")
+                                                    .setCardinality(
+                                                            PropertyConfig.CARDINALITY_OPTIONAL)
+                                                    .build())
+                                    .build())
+                    .build())
+            .get();
+
+        // Dispatch notifications
+        observer.waitForNotificationCount(1);
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), DB_NAME_1, ImmutableSet.of("Type2")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testAddObserver_schemaChange_contents_skipBySpec() throws Exception {
+        // Add a schema
+        mDb1.setSchemaAsync(
+                new SetSchemaRequest.Builder()
+                        .addSchemas(
+                                new AppSearchSchema.Builder("Type1")
+                                        .addProperty(
+                                                new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                                        "booleanProp")
+                                                        .setCardinality(
+                                                                PropertyConfig.CARDINALITY_REQUIRED)
+                                                        .build())
+                                        .build(),
+                                new AppSearchSchema.Builder("Type2")
+                                        .addProperty(
+                                                new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                                        "booleanProp")
+                                                        .setCardinality(
+                                                                PropertyConfig.CARDINALITY_REQUIRED)
+                                                        .build())
+                                        .build())
+                        .build())
+                .get();
+
+        // Register an observer that only listens for Type2
+        TestObserverCallback observer = new TestObserverCallback();
+        mGlobalSearchSession.registerObserverCallback(
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().addFilterSchemas("Type2").build(),
+                EXECUTOR,
+                observer);
+
+        // Update both types of the schema (changed cardinalities)
+        mDb1.setSchemaAsync(
+                new SetSchemaRequest.Builder()
+                        .addSchemas(
+                                new AppSearchSchema.Builder("Type1")
+                                        .addProperty(
+                                                new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                                        "booleanProp")
+                                                        .setCardinality(
+                                                                PropertyConfig.CARDINALITY_OPTIONAL)
+                                                        .build())
+                                        .build(),
+                                new AppSearchSchema.Builder("Type2")
+                                        .addProperty(
+                                                new AppSearchSchema.BooleanPropertyConfig.Builder(
+                                                        "booleanProp")
+                                                        .setCardinality(
+                                                                PropertyConfig.CARDINALITY_OPTIONAL)
+                                                        .build())
+                                        .build())
+                        .build())
+                .get();
+
+        observer.waitForNotificationCount(1);
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), DB_NAME_1, ImmutableSet.of("Type2")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
+
+    @Test
+    public void testRegisterObserver_schemaMigration() throws Exception {
+        // Add a schema with two types
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
+                .setVersion(1)
+                .addSchemas(
+                        new AppSearchSchema.Builder("Type1")
+                                .addProperty(
+                                        new AppSearchSchema.StringPropertyConfig.Builder("strProp1")
+                                                .build()
+                                ).build(),
+                        new AppSearchSchema.Builder("Type2")
+                                .addProperty(
+                                        new AppSearchSchema.LongPropertyConfig.Builder("longProp1")
+                                                .build()
+                                ).build()
+                        ).build()
+        ).get();
+
+        // Index some documents
+        GenericDocument type1doc1 = new GenericDocument.Builder<GenericDocument.Builder<?>>(
+                "namespace", "t1id1", "Type1")
+                .setPropertyString("strProp1", "t1id1 prop value")
+                .build();
+        GenericDocument type1doc2 = new GenericDocument.Builder<GenericDocument.Builder<?>>(
+                "namespace", "t1id2", "Type1")
+                .setPropertyString("strProp1", "t1id2 prop value")
+                .build();
+        GenericDocument type2doc1 = new GenericDocument.Builder<GenericDocument.Builder<?>>(
+                "namespace", "t2id1", "Type2")
+                .setPropertyLong("longProp1", 41)
+                .build();
+        GenericDocument type2doc2 = new GenericDocument.Builder<GenericDocument.Builder<?>>(
+                "namespace", "t2id2", "Type2")
+                .setPropertyLong("longProp1", 42)
+                .build();
+        mDb1.putAsync(new PutDocumentsRequest.Builder()
+                .addGenericDocuments(type1doc1, type1doc2, type2doc1, type2doc2)
+                .build())
+                .get();
+
+        // Register an observer that only listens for Type1
+        TestObserverCallback observer = new TestObserverCallback();
+        mGlobalSearchSession.registerObserverCallback(
+                /*targetPackageName=*/mContext.getPackageName(),
+                new ObserverSpec.Builder().addFilterSchemas("Type1").build(),
+                EXECUTOR,
+                observer);
+
+        // Update both types of the schema with migration to a new property name
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
+                .setVersion(2)
+                .addSchemas(
+                        new AppSearchSchema.Builder("Type1")
+                                .addProperty(
+                                        new AppSearchSchema.StringPropertyConfig.Builder("strProp2")
+                                                .build()
+                                ).build(),
+                        new AppSearchSchema.Builder("Type2")
+                                .addProperty(
+                                        new AppSearchSchema.LongPropertyConfig.Builder("longProp2")
+                                                .build()
+                                ).build()
+                        )
+                .setMigrator("Type1", new Migrator() {
+                    @Override
+                    public boolean shouldMigrate(int currentVersion, int finalVersion) {
+                        assertThat(currentVersion).isEqualTo(1);
+                        assertThat(finalVersion).isEqualTo(2);
+                        return true;
+                    }
+
+                    @NonNull
+                    @Override
+                    public GenericDocument onUpgrade(
+                            int currentVersion,
+                            int finalVersion,
+                            @NonNull GenericDocument document) {
+                        assertThat(currentVersion).isEqualTo(1);
+                        assertThat(finalVersion).isEqualTo(2);
+                        assertThat(document.getSchemaType()).isEqualTo("Type1");
+                        String[] prop = document.getPropertyStringArray("strProp1");
+                        assertThat(prop).isNotNull();
+                        return new GenericDocument.Builder<GenericDocument.Builder<?>>(
+                                document.getNamespace(),
+                                document.getId(),
+                                document.getSchemaType())
+                                .setPropertyString("strProp2", prop)
+                        .build();
+                    }
+
+                    @NonNull
+                    @Override
+                    public GenericDocument onDowngrade(
+                            int currentVersion,
+                            int finalVersion,
+                            @NonNull GenericDocument document) {
+                        // Doesn't happen in this test
+                        throw new UnsupportedOperationException();
+                    }
+                }).setMigrator("Type2", new Migrator() {
+                    @Override
+                    public boolean shouldMigrate(int currentVersion, int finalVersion) {
+                        assertThat(currentVersion).isEqualTo(1);
+                        assertThat(finalVersion).isEqualTo(2);
+                        return true;
+                    }
+
+                    @NonNull
+                    @Override
+                    public GenericDocument onUpgrade(
+                            int currentVersion,
+                            int finalVersion,
+                            @NonNull GenericDocument document) {
+                        assertThat(currentVersion).isEqualTo(1);
+                        assertThat(finalVersion).isEqualTo(2);
+                        assertThat(document.getSchemaType()).isEqualTo("Type2");
+                        long[] prop = document.getPropertyLongArray("longProp1");
+                        assertThat(prop).isNotNull();
+                        return new GenericDocument.Builder<GenericDocument.Builder<?>>(
+                                document.getNamespace(),
+                                document.getId(),
+                                document.getSchemaType())
+                                .setPropertyLong("longProp2", prop[0] + 1000)
+                        .build();
+                    }
+
+                    @NonNull
+                    @Override
+                    public GenericDocument onDowngrade(
+                            int currentVersion,
+                            int finalVersion,
+                            @NonNull GenericDocument document) {
+                        // Doesn't happen in this test
+                        throw new UnsupportedOperationException();
+                    }
+                })
+                .build()
+        ).get();
+
+        // Make sure the test is valid by checking that migration actually occurred
+        AppSearchBatchResult<String, GenericDocument> getResponse = mDb1.getByDocumentIdAsync(
+                new GetByDocumentIdRequest.Builder("namespace")
+                        .addIds("t1id1", "t1id2", "t2id1", "t2id2")
+                        .build())
+                .get();
+        assertThat(getResponse.isSuccess()).isTrue();
+        assertThat(getResponse.getSuccesses().get("t1id1").getPropertyString("strProp2"))
+                .isEqualTo("t1id1 prop value");
+        assertThat(getResponse.getSuccesses().get("t1id2").getPropertyString("strProp2"))
+                .isEqualTo("t1id2 prop value");
+        assertThat(getResponse.getSuccesses().get("t2id1").getPropertyLong("longProp2"))
+                .isEqualTo(1041);
+        assertThat(getResponse.getSuccesses().get("t2id2").getPropertyLong("longProp2"))
+                .isEqualTo(1042);
+
+        // Per the observer documentation, for schema migrations, individual document changes are
+        // not dispatched. Only SchemaChangeInfo is dispatched.
+        observer.waitForNotificationCount(1);
+        assertThat(observer.getSchemaChanges()).containsExactly(
+                new SchemaChangeInfo(
+                        mContext.getPackageName(), DB_NAME_1, ImmutableSet.of("Type1")));
+        assertThat(observer.getDocumentChanges()).isEmpty();
+    }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionLocalCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionLocalCtsTest.java
index 19af478..4c038e9 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionLocalCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionLocalCtsTest.java
@@ -25,7 +25,6 @@
 import androidx.annotation.NonNull;
 import androidx.appsearch.app.AppSearchResult;
 import androidx.appsearch.app.AppSearchSession;
-import androidx.appsearch.app.Features;
 import androidx.appsearch.app.GlobalSearchSession;
 import androidx.appsearch.app.PutDocumentsRequest;
 import androidx.appsearch.app.SearchResult;
@@ -46,39 +45,31 @@
 
 public class GlobalSearchSessionLocalCtsTest extends GlobalSearchSessionCtsTestBase {
     @Override
-    protected ListenableFuture<AppSearchSession> createSearchSession(@NonNull String dbName) {
+    protected ListenableFuture<AppSearchSession> createSearchSessionAsync(@NonNull String dbName) {
         Context context = ApplicationProvider.getApplicationContext();
-        return LocalStorage.createSearchSession(
+        return LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, dbName).build());
     }
 
     @Override
-    protected ListenableFuture<GlobalSearchSession> createGlobalSearchSession() {
+    protected ListenableFuture<GlobalSearchSession> createGlobalSearchSessionAsync() {
         Context context = ApplicationProvider.getApplicationContext();
-        return LocalStorage.createGlobalSearchSession(
+        return LocalStorage.createGlobalSearchSessionAsync(
                 new LocalStorage.GlobalSearchContext.Builder(context).build());
     }
 
-    @Test
-    public void testFeaturesSupported() {
-        assertThat(mDb1.getFeatures().isFeatureSupported(
-                Features.SEARCH_RESULT_MATCH_INFO_SUBMATCH)).isTrue();
-        assertThat(mDb1.getFeatures().isFeatureSupported(
-                Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER)).isTrue();
-    }
-
     // TODO(b/194207451) This test can be moved to CtsTestBase if customized logger is
     //  supported for platform backend.
     @Test
     public void testLogger_searchStatsLogged_forEmptyFirstPage() throws Exception {
         SimpleTestLogger logger = new SimpleTestLogger();
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = LocalStorage.createSearchSession(
+        AppSearchSession db2 = LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, DB_NAME_2)
                         .setLogger(logger).build()).get();
 
         // Schema registration
-        db2.setSchema(
+        db2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -96,10 +87,10 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(db2.put(
+        checkIsBatchResultSuccess(db2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1, inEmail2).build()));
 
-        GlobalSearchSession globalSearchSession = LocalStorage.createGlobalSearchSession(
+        GlobalSearchSession globalSearchSession = LocalStorage.createGlobalSearchSessionAsync(
                 new LocalStorage.GlobalSearchContext.Builder(context).setLogger(
                         logger).build()).get();
         assertThat(logger.mSearchStats).isNull();
@@ -113,7 +104,7 @@
                 .build());
 
         // Get first page
-        List<SearchResult> page = searchResults.getNextPage().get();
+        List<SearchResult> page = searchResults.getNextPageAsync().get();
         assertThat(page).hasSize(0);
 
         // Check searchStats has been set. We won't check all the fields here.
@@ -134,12 +125,12 @@
     public void testLogger_searchStatsLogged_forNonEmptyFirstPage() throws Exception {
         SimpleTestLogger logger = new SimpleTestLogger();
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = LocalStorage.createSearchSession(
+        AppSearchSession db2 = LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, DB_NAME_2)
                         .setLogger(logger).build()).get();
 
         // Schema registration
-        db2.setSchema(
+        db2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -157,10 +148,10 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(db2.put(
+        checkIsBatchResultSuccess(db2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1, inEmail2).build()));
 
-        GlobalSearchSession globalSearchSession = LocalStorage.createGlobalSearchSession(
+        GlobalSearchSession globalSearchSession = LocalStorage.createGlobalSearchSessionAsync(
                 new LocalStorage.GlobalSearchContext.Builder(context).setLogger(
                         logger).build()).get();
         assertThat(logger.mSearchStats).isNull();
@@ -174,7 +165,7 @@
                 .build());
 
         // Get first page
-        List<SearchResult> page = searchResults.getNextPage().get();
+        List<SearchResult> page = searchResults.getNextPageAsync().get();
         assertThat(page).hasSize(1);
 
         // Check searchStats has been set. We won't check all the fields here.
@@ -195,12 +186,12 @@
     public void testLogger_searchStatsLogged_forEmptySecondPage() throws Exception {
         SimpleTestLogger logger = new SimpleTestLogger();
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = LocalStorage.createSearchSession(
+        AppSearchSession db2 = LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, DB_NAME_2)
                         .setLogger(logger).build()).get();
 
         // Schema registration
-        db2.setSchema(
+        db2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -218,10 +209,10 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(db2.put(
+        checkIsBatchResultSuccess(db2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1, inEmail2).build()));
 
-        GlobalSearchSession globalSearchSession = LocalStorage.createGlobalSearchSession(
+        GlobalSearchSession globalSearchSession = LocalStorage.createGlobalSearchSessionAsync(
                 new LocalStorage.GlobalSearchContext.Builder(context).setLogger(
                         logger).build()).get();
         assertThat(logger.mSearchStats).isNull();
@@ -235,12 +226,12 @@
                 .build());
 
         // Get first page
-        List<SearchResult> page = searchResults.getNextPage().get();
+        List<SearchResult> page = searchResults.getNextPageAsync().get();
         assertThat(page).hasSize(2);
 
         // Get second(empty) page
         logger.mSearchStats = null;
-        page = searchResults.getNextPage().get();
+        page = searchResults.getNextPageAsync().get();
         assertThat(page).hasSize(0);
 
         // Check searchStats has been set. We won't check all the fields here.
@@ -261,12 +252,12 @@
     public void testLogger_searchStatsLogged_forNonEmptySecondPage() throws Exception {
         SimpleTestLogger logger = new SimpleTestLogger();
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession db2 = LocalStorage.createSearchSession(
+        AppSearchSession db2 = LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, DB_NAME_2)
                         .setLogger(logger).build()).get();
 
         // Schema registration
-        db2.setSchema(
+        db2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
         // Index documents
@@ -284,10 +275,10 @@
                         .setSubject("testPut example")
                         .setBody("This is the body of the testPut email")
                         .build();
-        checkIsBatchResultSuccess(db2.put(
+        checkIsBatchResultSuccess(db2.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1, inEmail2).build()));
 
-        GlobalSearchSession globalSearchSession = LocalStorage.createGlobalSearchSession(
+        GlobalSearchSession globalSearchSession = LocalStorage.createGlobalSearchSessionAsync(
                 new LocalStorage.GlobalSearchContext.Builder(context).setLogger(
                         logger).build()).get();
         assertThat(logger.mSearchStats).isNull();
@@ -301,12 +292,12 @@
                 .build());
 
         // Get first page
-        List<SearchResult> page = searchResults.getNextPage().get();
+        List<SearchResult> page = searchResults.getNextPageAsync().get();
         assertThat(page).hasSize(1);
 
         // Get second page
         logger.mSearchStats = null;
-        page = searchResults.getNextPage().get();
+        page = searchResults.getNextPageAsync().get();
         assertThat(page).hasSize(1);
 
         // Check searchStats has been set. We won't check all the fields here.
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionPlatformCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionPlatformCtsTest.java
index 9d152ff..46aa5c4 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionPlatformCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionPlatformCtsTest.java
@@ -16,14 +16,11 @@
 // @exportToFramework:skipFile()
 package androidx.appsearch.cts.app;
 
-import static com.google.common.truth.Truth.assertThat;
-
 import android.content.Context;
 import android.os.Build;
 
 import androidx.annotation.NonNull;
 import androidx.appsearch.app.AppSearchSession;
-import androidx.appsearch.app.Features;
 import androidx.appsearch.app.GlobalSearchSession;
 import androidx.appsearch.platformstorage.PlatformStorage;
 import androidx.test.core.app.ApplicationProvider;
@@ -31,33 +28,19 @@
 
 import com.google.common.util.concurrent.ListenableFuture;
 
-import org.junit.Ignore;
-import org.junit.Test;
-
 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
 public class GlobalSearchSessionPlatformCtsTest extends GlobalSearchSessionCtsTestBase {
     @Override
-    protected ListenableFuture<AppSearchSession> createSearchSession(@NonNull String dbName) {
+    protected ListenableFuture<AppSearchSession> createSearchSessionAsync(@NonNull String dbName) {
         Context context = ApplicationProvider.getApplicationContext();
-        return PlatformStorage.createSearchSession(
+        return PlatformStorage.createSearchSessionAsync(
                 new PlatformStorage.SearchContext.Builder(context, dbName).build());
     }
 
     @Override
-    protected ListenableFuture<GlobalSearchSession> createGlobalSearchSession() {
+    protected ListenableFuture<GlobalSearchSession> createGlobalSearchSessionAsync() {
         Context context = ApplicationProvider.getApplicationContext();
-        return PlatformStorage.createGlobalSearchSession(
+        return PlatformStorage.createGlobalSearchSessionAsync(
                 new PlatformStorage.GlobalSearchContext.Builder(context).build());
     }
-
-    @Ignore("Unignore this test once these features are implemented in the platform backend.")
-    @Test
-    public void testFeaturesSupported() {
-        assertThat(mDb1.getFeatures().isFeatureSupported(
-                Features.SEARCH_RESULT_MATCH_INFO_SUBMATCH))
-                .isEqualTo(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S);
-        assertThat(mDb1.getFeatures().isFeatureSupported(
-                Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER))
-                .isEqualTo(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S);
-    }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/PutDocumentsRequestCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/PutDocumentsRequestCtsTest.java
index 372a090..c2b06d4 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/PutDocumentsRequestCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/PutDocumentsRequestCtsTest.java
@@ -74,12 +74,12 @@
         // A schema with Card must be set in order to be able to add a Card instance to
         // PutDocumentsRequest.
         Context context = ApplicationProvider.getApplicationContext();
-        AppSearchSession session = LocalStorage.createSearchSession(
+        AppSearchSession session = LocalStorage.createSearchSessionAsync(
                 new LocalStorage.SearchContext.Builder(context, /*databaseName=*/ "")
                         .build()
         ).get();
-        session.setSchema(new SetSchemaRequest.Builder().addDocumentClasses(Card.class).build())
-            .get();
+        session.setSchemaAsync(
+                new SetSchemaRequest.Builder().addDocumentClasses(Card.class).build()).get();
 
         Set<Card> cards = ImmutableSet.of(new Card("cardNamespace", "cardId", "cardProperty"));
         PutDocumentsRequest request = new PutDocumentsRequest.Builder().addDocuments(cards)
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SetSchemaRequestCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SetSchemaRequestCtsTest.java
index a965ef6..dd47914 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SetSchemaRequestCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SetSchemaRequestCtsTest.java
@@ -220,6 +220,87 @@
     }
 
     @Test
+    public void testSetSchemaTypeVisibleForPermissions() {
+        AppSearchSchema schema = new AppSearchSchema.Builder("Schema").build();
+
+        // By default, the schema is displayed.
+        SetSchemaRequest request =
+                new SetSchemaRequest.Builder().addSchemas(schema).build();
+        assertThat(request.getRequiredPermissionsForSchemaTypeVisibility()).isEmpty();
+
+        SetSchemaRequest.Builder setSchemaRequestBuilder = new SetSchemaRequest.Builder()
+                .addSchemas(schema)
+                .addRequiredPermissionsForSchemaTypeVisibility("Schema",
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR))
+                .addRequiredPermissionsForSchemaTypeVisibility("Schema",
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA));
+
+        request = setSchemaRequestBuilder.build();
+
+        assertThat(request.getRequiredPermissionsForSchemaTypeVisibility())
+                .containsExactly("Schema", ImmutableSet.of(
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS,
+                                SetSchemaRequest.READ_CALENDAR),
+                        ImmutableSet.of(SetSchemaRequest
+                                .READ_HOME_APP_SEARCH_DATA)));
+    }
+
+    @Test
+    public void testClearSchemaTypeVisibleForPermissions() {
+        SetSchemaRequest.Builder setSchemaRequestBuilder = new SetSchemaRequest.Builder()
+                .addSchemas(
+                        new AppSearchSchema.Builder("Schema1").build(),
+                        new AppSearchSchema.Builder("Schema2").build())
+                .addRequiredPermissionsForSchemaTypeVisibility(
+                        "Schema1",
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR))
+                .addRequiredPermissionsForSchemaTypeVisibility(
+                        "Schema1",
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA))
+                .addRequiredPermissionsForSchemaTypeVisibility(
+                        "Schema2",
+                        ImmutableSet.of(SetSchemaRequest.READ_EXTERNAL_STORAGE));
+
+        SetSchemaRequest request = setSchemaRequestBuilder.build();
+
+        assertThat(request.getRequiredPermissionsForSchemaTypeVisibility())
+                .containsExactly(
+                        "Schema1", ImmutableSet.of(
+                                ImmutableSet.of(
+                                        SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR),
+                                ImmutableSet.of(
+                                        SetSchemaRequest.READ_HOME_APP_SEARCH_DATA)),
+                        "Schema2", ImmutableSet.of(
+                                ImmutableSet.of(SetSchemaRequest.READ_EXTERNAL_STORAGE)
+                        )
+            );
+
+        // Clear the permissions in the builder
+        setSchemaRequestBuilder.clearRequiredPermissionsForSchemaTypeVisibility("Schema1");
+
+        // New object should be updated
+        assertThat(setSchemaRequestBuilder.build().getRequiredPermissionsForSchemaTypeVisibility())
+                .containsExactly(
+                        "Schema2", ImmutableSet.of(
+                                ImmutableSet.of(SetSchemaRequest.READ_EXTERNAL_STORAGE)
+                        )
+            );
+
+        // Old object should remain unchanged
+        assertThat(request.getRequiredPermissionsForSchemaTypeVisibility())
+                .containsExactly(
+                        "Schema1", ImmutableSet.of(
+                                ImmutableSet.of(
+                                        SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR),
+                                ImmutableSet.of(
+                                        SetSchemaRequest.READ_HOME_APP_SEARCH_DATA)),
+                        "Schema2", ImmutableSet.of(
+                                ImmutableSet.of(SetSchemaRequest.READ_EXTERNAL_STORAGE)
+                        )
+            );
+    }
+
+    @Test
     public void testSchemaTypeVisibilityForPackage_visible() {
         AppSearchSchema schema = new AppSearchSchema.Builder("Schema").build();
 
@@ -380,6 +461,29 @@
     }
 
     @Test
+    public void testSetDocumentClassVisibleForPermission() throws Exception {
+        // By default, the schema is displayed.
+        SetSchemaRequest request =
+                new SetSchemaRequest.Builder().addDocumentClasses(Card.class).build();
+        assertThat(request.getRequiredPermissionsForSchemaTypeVisibility()).isEmpty();
+
+        SetSchemaRequest.Builder setSchemaRequestBuilder = new SetSchemaRequest.Builder()
+                .addDocumentClasses(Card.class)
+                .addRequiredPermissionsForDocumentClassVisibility(Card.class,
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR))
+                .addRequiredPermissionsForDocumentClassVisibility(Card.class,
+                ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA));
+        request = setSchemaRequestBuilder.build();
+
+        assertThat(request.getRequiredPermissionsForSchemaTypeVisibility())
+                .containsExactly("Card", ImmutableSet.of(
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS,
+                                SetSchemaRequest.READ_CALENDAR),
+                        ImmutableSet.of(SetSchemaRequest
+                                .READ_HOME_APP_SEARCH_DATA)));
+    }
+
+    @Test
     public void testSetDocumentClassVisibilityForPackage_visible() throws Exception {
         // By default, the schema is not visible.
         SetSchemaRequest request =
@@ -478,6 +582,58 @@
                 "King");
     }
 
+    @Test
+    public void testClearDocumentClassVisibleForPermissions() throws Exception {
+        SetSchemaRequest.Builder setSchemaRequestBuilder = new SetSchemaRequest.Builder()
+                .addDocumentClasses(King.class, Queen.class)
+                .addRequiredPermissionsForDocumentClassVisibility(
+                        King.class,
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR))
+                .addRequiredPermissionsForDocumentClassVisibility(
+                        King.class,
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA))
+                .addRequiredPermissionsForDocumentClassVisibility(
+                        Queen.class,
+                        ImmutableSet.of(SetSchemaRequest.READ_EXTERNAL_STORAGE));
+
+        SetSchemaRequest request = setSchemaRequestBuilder.build();
+
+        assertThat(request.getRequiredPermissionsForSchemaTypeVisibility())
+                .containsExactly(
+                        "King", ImmutableSet.of(
+                                ImmutableSet.of(
+                                        SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR),
+                                ImmutableSet.of(
+                                        SetSchemaRequest.READ_HOME_APP_SEARCH_DATA)),
+                        "Queen", ImmutableSet.of(
+                                ImmutableSet.of(SetSchemaRequest.READ_EXTERNAL_STORAGE)
+                        )
+            );
+
+        // Clear the permissions in the builder
+        setSchemaRequestBuilder.clearRequiredPermissionsForDocumentClassVisibility(King.class);
+
+        // New object should be updated
+        assertThat(setSchemaRequestBuilder.build().getRequiredPermissionsForSchemaTypeVisibility())
+                .containsExactly(
+                        "Queen", ImmutableSet.of(
+                                ImmutableSet.of(SetSchemaRequest.READ_EXTERNAL_STORAGE)
+                        )
+            );
+
+        // Old object should remain unchanged
+        assertThat(request.getRequiredPermissionsForSchemaTypeVisibility())
+                .containsExactly(
+                        "King", ImmutableSet.of(
+                                ImmutableSet.of(
+                                        SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR),
+                                ImmutableSet.of(
+                                        SetSchemaRequest.READ_HOME_APP_SEARCH_DATA)),
+                        "Queen", ImmutableSet.of(
+                                ImmutableSet.of(SetSchemaRequest.READ_EXTERNAL_STORAGE)
+                        )
+            );
+    }
 // @exportToFramework:endStrip()
 
     @Test
@@ -498,4 +654,130 @@
         assertThat(exception).hasMessageThat().contains(
                 "Cannot set version to the request if schema is empty.");
     }
+
+    @Test
+    public void testRebuild() {
+        byte[] sha256cert1 = new byte[32];
+        byte[] sha256cert2 = new byte[32];
+        Arrays.fill(sha256cert1, (byte) 1);
+        Arrays.fill(sha256cert2, (byte) 2);
+        PackageIdentifier packageIdentifier1 = new PackageIdentifier("Email", sha256cert1);
+        PackageIdentifier packageIdentifier2 = new PackageIdentifier("Email", sha256cert2);
+        AppSearchSchema schema1 = new AppSearchSchema.Builder("Email1")
+                .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("subject")
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(
+                                AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).build();
+        AppSearchSchema schema2 = new AppSearchSchema.Builder("Email2")
+                .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("subject")
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(
+                                AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).build();
+
+        SetSchemaRequest.Builder builder = new SetSchemaRequest.Builder()
+                .addSchemas(schema1)
+                .setVersion(37)
+                .setSchemaTypeDisplayedBySystem("Email1", /*displayed=*/false)
+                .setSchemaTypeVisibilityForPackage(
+                        "Email1", /*visible=*/true, packageIdentifier1)
+                .addRequiredPermissionsForSchemaTypeVisibility("Email1",
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS,
+                                SetSchemaRequest.READ_CALENDAR))
+                .addRequiredPermissionsForSchemaTypeVisibility("Email1",
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA));
+
+        SetSchemaRequest original = builder.build();
+        SetSchemaRequest rebuild = builder.addSchemas(schema2)
+                .setVersion(42)
+                .setSchemaTypeDisplayedBySystem("Email2", /*displayed=*/false)
+                .setSchemaTypeVisibilityForPackage(
+                        "Email2", /*visible=*/true, packageIdentifier2)
+                .addRequiredPermissionsForSchemaTypeVisibility("Email2",
+                        ImmutableSet.of(SetSchemaRequest.READ_CONTACTS,
+                                SetSchemaRequest.READ_EXTERNAL_STORAGE))
+                .addRequiredPermissionsForSchemaTypeVisibility("Email2",
+                        ImmutableSet.of(SetSchemaRequest.READ_ASSISTANT_APP_SEARCH_DATA))
+                .build();
+
+        assertThat(original.getSchemas()).containsExactly(schema1);
+        assertThat(original.getVersion()).isEqualTo(37);
+        assertThat(original.getSchemasNotDisplayedBySystem()).containsExactly("Email1");
+        assertThat(original.getSchemasVisibleToPackages()).containsExactly(
+                "Email1", ImmutableSet.of(packageIdentifier1));
+        assertThat(original.getRequiredPermissionsForSchemaTypeVisibility()).containsExactly(
+                "Email1",
+                ImmutableSet.of(
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS,
+                                SetSchemaRequest.READ_CALENDAR),
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA)));
+
+        assertThat(rebuild.getSchemas()).containsExactly(schema1, schema2);
+        assertThat(rebuild.getVersion()).isEqualTo(42);
+        assertThat(rebuild.getSchemasNotDisplayedBySystem()).containsExactly("Email1", "Email2");
+        assertThat(rebuild.getSchemasVisibleToPackages()).containsExactly(
+                "Email1", ImmutableSet.of(packageIdentifier1),
+                "Email2", ImmutableSet.of(packageIdentifier2));
+        assertThat(rebuild.getRequiredPermissionsForSchemaTypeVisibility()).containsExactly(
+                "Email1",
+                ImmutableSet.of(
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS,
+                                SetSchemaRequest.READ_CALENDAR),
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA)),
+                "Email2",
+                ImmutableSet.of(
+                        ImmutableSet.of(SetSchemaRequest.READ_CONTACTS,
+                                SetSchemaRequest.READ_EXTERNAL_STORAGE),
+                        ImmutableSet.of(SetSchemaRequest.READ_ASSISTANT_APP_SEARCH_DATA)));
+    }
+
+    @Test
+    public void getAndModify() {
+        byte[] sha256cert1 = new byte[32];
+        byte[] sha256cert2 = new byte[32];
+        Arrays.fill(sha256cert1, (byte) 1);
+        Arrays.fill(sha256cert2, (byte) 2);
+        PackageIdentifier packageIdentifier1 = new PackageIdentifier("Email", sha256cert1);
+        PackageIdentifier packageIdentifier2 = new PackageIdentifier("Email", sha256cert2);
+        AppSearchSchema schema1 = new AppSearchSchema.Builder("Email1")
+                .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("subject")
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(
+                                AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).build();
+
+        SetSchemaRequest request = new SetSchemaRequest.Builder()
+                .addSchemas(schema1)
+                .setVersion(37)
+                .setSchemaTypeDisplayedBySystem("Email1", /*displayed=*/false)
+                .setSchemaTypeVisibilityForPackage(
+                        "Email1", /*visible=*/true, packageIdentifier1)
+                .addRequiredPermissionsForSchemaTypeVisibility("Email1",
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR))
+                .addRequiredPermissionsForSchemaTypeVisibility("Email1",
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA))
+                .build();
+
+        // get the visibility setting and modify the output object.
+        // skip getSchemasNotDisplayedBySystem since it returns an unmodifiable object.
+        request.getSchemasVisibleToPackages().put("Email2", ImmutableSet.of(packageIdentifier2));
+        request.getRequiredPermissionsForSchemaTypeVisibility().put("Email2",
+                ImmutableSet.of(ImmutableSet.of(SetSchemaRequest.READ_CALENDAR)));
+
+        // verify we still get the original object.
+        assertThat(request.getSchemasVisibleToPackages()).containsExactly("Email1",
+                ImmutableSet.of(packageIdentifier1));
+        assertThat(request.getRequiredPermissionsForSchemaTypeVisibility()).containsExactly(
+                "Email1",
+                ImmutableSet.of(
+                        ImmutableSet.of(SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR),
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA)));
+    }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/observer/DocumentChangeInfoCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/observer/DocumentChangeInfoCtsTest.java
new file mode 100644
index 0000000..06f1bd4
--- /dev/null
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/observer/DocumentChangeInfoCtsTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2022 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.appsearch.cts.observer;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.appsearch.observer.DocumentChangeInfo;
+
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.Test;
+
+public class DocumentChangeInfoCtsTest {
+    @Test
+    public void testConstructor() {
+        DocumentChangeInfo DocumentChangeInfo = new DocumentChangeInfo(
+                "packageName",
+                "databaseName",
+                "namespace",
+                "SchemaName",
+                ImmutableSet.of("documentId1", "documentId2"));
+        assertThat(DocumentChangeInfo.getPackageName()).isEqualTo("packageName");
+        assertThat(DocumentChangeInfo.getDatabaseName()).isEqualTo("databaseName");
+        assertThat(DocumentChangeInfo.getNamespace()).isEqualTo("namespace");
+        assertThat(DocumentChangeInfo.getSchemaName()).isEqualTo("SchemaName");
+        assertThat(DocumentChangeInfo.getChangedDocumentIds())
+                .containsExactly("documentId1", "documentId2");
+    }
+
+    @Test
+    public void testEqualsAndHasCode() {
+        DocumentChangeInfo info1Copy1 = new DocumentChangeInfo(
+                "packageName",
+                "databaseName",
+                "namespace",
+                "SchemaName",
+                ImmutableSet.of("documentId1", "documentId2"));
+        DocumentChangeInfo info1Copy2 = new DocumentChangeInfo(
+                "packageName",
+                "databaseName",
+                "namespace",
+                "SchemaName",
+                ImmutableSet.of("documentId1", "documentId2"));
+        DocumentChangeInfo info2 = new DocumentChangeInfo(
+                "packageName",
+                "databaseName",
+                "namespace",
+                "SchemaName",
+                ImmutableSet.of("documentId3", "documentId2"));
+
+        assertThat(info1Copy1).isEqualTo(info1Copy2);
+        assertThat(info1Copy1.hashCode()).isEqualTo(info1Copy2.hashCode());
+        assertThat(info1Copy1).isNotEqualTo(info2);
+        assertThat(info1Copy1.hashCode()).isNotEqualTo(info2.hashCode());
+    }
+}
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/observer/ObserverSpecCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/observer/ObserverSpecCtsTest.java
new file mode 100644
index 0000000..ae321af
--- /dev/null
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/observer/ObserverSpecCtsTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2022 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.appsearch.cts.observer;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.appsearch.annotation.Document;
+import androidx.appsearch.observer.ObserverSpec;
+
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.Test;
+
+public class ObserverSpecCtsTest {
+    @Test
+    public void testFilterSchemas() {
+        ObserverSpec observerSpec = new ObserverSpec.Builder()
+                .addFilterSchemas("Schema1", "Schema2")
+                .addFilterSchemas(ImmutableSet.of("Schema3", "Schema4"))
+                .build();
+        assertThat(observerSpec.getFilterSchemas()).containsExactly(
+                "Schema1", "Schema2", "Schema3", "Schema4");
+    }
+
+// @exportToFramework:startStrip()
+
+    @Document
+    public static class King {
+        @Document.Namespace String mNamespace;
+        @Document.Id String mId;
+    }
+
+    @Document
+    public static class Queen {
+        @Document.Namespace String mNamespace;
+        @Document.Id String mId;
+    }
+
+    @Document
+    public static class Jack {
+        @Document.Namespace String mNamespace;
+        @Document.Id String mId;
+    }
+
+    @Document
+    public static class Ace {
+        @Document.Namespace String mNamespace;
+        @Document.Id String mId;
+    }
+
+    @Test
+    public void testFilterSchemas_documentClass() throws Exception {
+        ObserverSpec observerSpec = new ObserverSpec.Builder()
+                .addFilterSchemas("Schema1", "Schema2")
+                .addFilterDocumentClasses(King.class, Queen.class)
+                .addFilterSchemas(ImmutableSet.of("Schema3", "Schema4"))
+                .addFilterDocumentClasses(ImmutableSet.of(Jack.class, Ace.class))
+                .build();
+        assertThat(observerSpec.getFilterSchemas()).containsExactly(
+                "Schema1", "Schema2", "King", "Queen", "Schema3", "Schema4", "Jack", "Ace");
+    }
+
+// @exportToFramework:endStrip()
+}
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/observer/SchemaChangeInfoCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/observer/SchemaChangeInfoCtsTest.java
new file mode 100644
index 0000000..3289177
--- /dev/null
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/observer/SchemaChangeInfoCtsTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2022 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.appsearch.cts.observer;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.appsearch.observer.SchemaChangeInfo;
+
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.Test;
+
+public class SchemaChangeInfoCtsTest {
+    @Test
+    public void testConstructor() {
+        SchemaChangeInfo schemaChangeInfo = new SchemaChangeInfo(
+                "packageName", "databaseName", ImmutableSet.of("schemaName1", "schemaName2"));
+        assertThat(schemaChangeInfo.getPackageName()).isEqualTo("packageName");
+        assertThat(schemaChangeInfo.getDatabaseName()).isEqualTo("databaseName");
+        assertThat(schemaChangeInfo.getChangedSchemaNames())
+                .containsExactly("schemaName1", "schemaName2");
+    }
+
+    @Test
+    public void testEqualsAndHasCode() {
+        SchemaChangeInfo info1Copy1 = new SchemaChangeInfo(
+                "packageName", "databaseName", ImmutableSet.of("schemaName1", "schemaName2"));
+        SchemaChangeInfo info1Copy2 = new SchemaChangeInfo(
+                "packageName", "databaseName", ImmutableSet.of("schemaName1", "schemaName2"));
+        SchemaChangeInfo info2 = new SchemaChangeInfo(
+                "packageName", "databaseName", ImmutableSet.of("schemaName3", "schemaName2"));
+
+        assertThat(info1Copy1).isEqualTo(info1Copy2);
+        assertThat(info1Copy1.hashCode()).isEqualTo(info1Copy2.hashCode());
+        assertThat(info1Copy1).isNotEqualTo(info2);
+        assertThat(info1Copy1.hashCode()).isNotEqualTo(info2.hashCode());
+    }
+}
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/Document.java b/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/Document.java
index 527127f..ef685c1 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/Document.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/Document.java
@@ -220,7 +220,7 @@
          * <p>This attribute does not apply to properties of a repeated type (e.g. a list).
          *
          * <p>Please make sure you understand the consequences of required fields on
-         * {@link androidx.appsearch.app.AppSearchSession#setSchema schema migration} before setting
+         * {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync schema migration} before setting
          * this attribute to {@code true}.
          */
         boolean required() default false;
@@ -256,7 +256,7 @@
          * <p>This attribute does not apply to properties of a repeated type (e.g. a list).
          *
          * <p>Please make sure you understand the consequences of required fields on
-         * {@link androidx.appsearch.app.AppSearchSession#setSchema schema migration} before setting
+         * {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync schema migration} before setting
          * this attribute to {@code true}.
          */
         boolean required() default false;
@@ -280,7 +280,7 @@
          * <p>This attribute does not apply to properties of a repeated type (e.g. a list).
          *
          * <p>Please make sure you understand the consequences of required fields on
-         * {@link androidx.appsearch.app.AppSearchSession#setSchema schema migration} before setting
+         * {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync schema migration} before setting
          * this attribute to {@code true}.
          */
         boolean required() default false;
@@ -307,7 +307,7 @@
          * <p>This attribute does not apply to properties of a repeated type (e.g. a list).
          *
          * <p>Please make sure you understand the consequences of required fields on
-         * {@link androidx.appsearch.app.AppSearchSession#setSchema schema migration} before setting
+         * {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync schema migration} before setting
          * this attribute to {@code true}.
          */
         boolean required() default false;
@@ -331,7 +331,7 @@
          * <p>This attribute does not apply to properties of a repeated type (e.g. a list).
          *
          * <p>Please make sure you understand the consequences of required fields on
-         * {@link androidx.appsearch.app.AppSearchSession#setSchema schema migration} before setting
+         * {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync schema migration} before setting
          * this attribute to {@code true}.
          */
         boolean required() default false;
@@ -355,7 +355,7 @@
          * <p>This attribute does not apply to properties of a repeated type (e.g. a list).
          *
          * <p>Please make sure you understand the consequences of required fields on
-         * {@link androidx.appsearch.app.AppSearchSession#setSchema schema migration} before setting
+         * {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync schema migration} before setting
          * this attribute to {@code true}.
          */
         boolean required() default false;
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchBatchResult.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchBatchResult.java
index 4b6ee7c..3cdf6ce 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchBatchResult.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchBatchResult.java
@@ -37,9 +37,9 @@
  * @param <KeyType> The type of the keys for which the results will be reported.
  * @param <ValueType> The type of the result objects for successful results.
  *
- * @see AppSearchSession#put
- * @see AppSearchSession#getByDocumentId
- * @see AppSearchSession#remove
+ * @see AppSearchSession#putAsync
+ * @see AppSearchSession#getByDocumentIdAsync
+ * @see AppSearchSession#removeAsync
  */
 public final class AppSearchBatchResult<KeyType, ValueType> {
     @NonNull private final Map<KeyType, ValueType> mSuccesses;
@@ -64,9 +64,9 @@
      * Returns a {@link Map} of keys mapped to instances of the value type for all successful
      * individual results.
      *
-     * <p>Example: {@link AppSearchSession#getByDocumentId} returns an {@link AppSearchBatchResult}.
-     * Each key (the document ID, of {@code String} type) will map to a {@link GenericDocument}
-     * object.
+     * <p>Example: {@link AppSearchSession#getByDocumentIdAsync} returns an
+     * {@link AppSearchBatchResult}. Each key (the document ID, of {@code String} type) will map to
+     * a {@link GenericDocument} object.
      *
      * <p>The values of the {@link Map} will not be {@code null}.
      */
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSchema.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSchema.java
index 84795f9..c3e8b5e 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSchema.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSchema.java
@@ -44,7 +44,7 @@
  *
  * <p>The schema consists of type information, properties, and config (like tokenization type).
  *
- * @see AppSearchSession#setSchema
+ * @see AppSearchSession#setSchemaAsync
  */
 public final class AppSearchSchema {
     private static final String SCHEMA_TYPE_FIELD = "schemaType";
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSession.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSession.java
index d423da0..be67b84f 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSession.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSession.java
@@ -32,7 +32,8 @@
  * a schema, adding documents, and searching.
  *
  * <p>Instances of this interface are usually obtained from a storage implementation, e.g.
- * {@code LocalStorage.createSearchSession()} or {@code PlatformStorage.createSearchSession()}.
+ * {@code LocalStorage.createSearchSessionAsync()} or
+ * {@code PlatformStorage.createSearchSessionAsync()}.
  *
  * <p>All implementations of this interface must be thread safe.
  *
@@ -44,42 +45,75 @@
      * Sets the schema that represents the organizational structure of data within the AppSearch
      * database.
      *
-     * <p>Upon creating an {@link AppSearchSession}, {@link #setSchema} should be called. If the
-     * schema needs to be updated, or it has not been previously set, then the provided schema
-     * will be saved and persisted to disk. Otherwise, {@link #setSchema} is handled efficiently
-     * as a no-op call.
+     * <p>Upon creating an {@link AppSearchSession}, {@link #setSchemaAsync} should be called. If
+     * the schema needs to be updated, or it has not been previously set, then the provided schema
+     * will be saved and persisted to disk. Otherwise, {@link #setSchemaAsync} is handled
+     * efficiently as a no-op call.
      *
      * @param  request the schema to set or update the AppSearch database to.
      * @return a {@link ListenableFuture} which resolves to a {@link SetSchemaResponse} object.
      */
     @NonNull
-    ListenableFuture<SetSchemaResponse> setSchema(
-            @NonNull SetSchemaRequest request);
+    ListenableFuture<SetSchemaResponse> setSchemaAsync(@NonNull SetSchemaRequest request);
 
     /**
-     * Retrieves the schema most recently successfully provided to {@link #setSchema}.
+     * @deprecated use {@link #setSchemaAsync}
+     * @param  request the schema to set or update the AppSearch database to.
+     * @return a {@link ListenableFuture} which resolves to a {@link SetSchemaResponse} object.
+     */
+    @NonNull
+    @Deprecated
+    default ListenableFuture<SetSchemaResponse> setSchema(
+            @NonNull SetSchemaRequest request) {
+        return setSchemaAsync(request);
+    }
+
+    /**
+     * Retrieves the schema most recently successfully provided to {@link #setSchemaAsync}.
      *
      * @return The pending {@link GetSchemaResponse} of performing this operation.
      */
     // This call hits disk; async API prevents us from treating these calls as properties.
     @SuppressLint("KotlinPropertyAccess")
     @NonNull
-    ListenableFuture<GetSchemaResponse> getSchema();
+    ListenableFuture<GetSchemaResponse> getSchemaAsync();
+
+    /**
+     * @deprecated use {@link #getSchemaAsync}
+     *
+     * @return The pending {@link GetSchemaResponse} of performing this operation.
+     */
+    // This call hits disk; async API prevents us from treating these calls as properties.
+    @SuppressLint("KotlinPropertyAccess")
+    @NonNull
+    @Deprecated
+    default ListenableFuture<GetSchemaResponse> getSchema() {
+        return getSchemaAsync();
+    }
 
     /**
      * Retrieves the set of all namespaces in the current database with at least one document.
      *
-     * @return The pending result of performing this operation.
-     */
+     * @return The pending result of performing this operation. */
     @NonNull
-    ListenableFuture<Set<String>> getNamespaces();
+    ListenableFuture<Set<String>> getNamespacesAsync();
+
+    /**
+     * @deprecated use {@link #getNamespacesAsync()}
+     *
+     * @return The pending result of performing this operation. */
+    @NonNull
+    @Deprecated
+    default ListenableFuture<Set<String>> getNamespaces() {
+        return getNamespacesAsync();
+    }
 
     /**
      * Indexes documents into the {@link AppSearchSession} database.
      *
      * <p>Each {@link GenericDocument} object must have a {@code schemaType} field set to an
      * {@link AppSearchSchema} type that has been previously registered by calling the
-     * {@link #setSchema} method.
+     * {@link #setSchemaAsync} method.
      *
      * @param request containing documents to be indexed.
      * @return a {@link ListenableFuture} which resolves to an {@link AppSearchBatchResult}.
@@ -88,7 +122,24 @@
      * or a failed {@link AppSearchResult} otherwise.
      */
     @NonNull
-    ListenableFuture<AppSearchBatchResult<String, Void>> put(@NonNull PutDocumentsRequest request);
+    ListenableFuture<AppSearchBatchResult<String, Void>> putAsync(
+            @NonNull PutDocumentsRequest request);
+
+    /**
+     * @deprecated use {@link #putAsync}
+     *
+     * @param request containing documents to be indexed.
+     * @return a {@link ListenableFuture} which resolves to an {@link AppSearchBatchResult}.
+     * The keys of the returned {@link AppSearchBatchResult} are the IDs of the input documents.
+     * The values are either {@code null} if the corresponding document was successfully indexed,
+     * or a failed {@link AppSearchResult} otherwise.
+     */
+    @NonNull
+    @Deprecated
+    default ListenableFuture<AppSearchBatchResult<String, Void>> put(
+            @NonNull PutDocumentsRequest request) {
+        return putAsync(request);
+    }
 
     /**
      * Gets {@link GenericDocument} objects by document IDs in a namespace from the
@@ -104,10 +155,29 @@
      * {@link AppSearchResult#RESULT_NOT_FOUND}.
      */
     @NonNull
-    ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentId(
+    ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentIdAsync(
             @NonNull GetByDocumentIdRequest request);
 
     /**
+     * @deprecated use {@link #getByDocumentIdAsync}
+     *
+     * @param request a request containing a namespace and IDs to get documents for.
+     * @return A {@link ListenableFuture} which resolves to an {@link AppSearchBatchResult}.
+     * The keys of the {@link AppSearchBatchResult} represent the input document IDs from the
+     * {@link GetByDocumentIdRequest} object. The values are either the corresponding
+     * {@link GenericDocument} object for the ID on success, or an {@link AppSearchResult}
+     * object on failure. For example, if an ID is not found, the value for that ID will be set
+     * to an {@link AppSearchResult} object with result code:
+     * {@link AppSearchResult#RESULT_NOT_FOUND}.
+     */
+    @NonNull
+    @Deprecated
+    default ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentId(
+            @NonNull GetByDocumentIdRequest request) {
+        return getByDocumentIdAsync(request);
+    }
+
+    /**
      * Retrieves documents from the open {@link AppSearchSession} that match a given query string
      * and type of search provided.
      *
@@ -164,7 +234,7 @@
      * adding projection, can be set by calling the corresponding {@link SearchSpec.Builder} setter.
      *
      * <p>This method is lightweight. The heavy work will be done in
-     * {@link SearchResults#getNextPage}.
+     * {@link SearchResults#getNextPageAsync}.
      *
      * @param queryExpression query string to search.
      * @param searchSpec      spec for setting document filters, adding projection, setting term
@@ -179,9 +249,9 @@
      *
      * <p>A usage report represents an event in which a user interacted with or viewed a document.
      *
-     * <p>For each call to {@link #reportUsage}, AppSearch updates usage count and usage recency
-     * metrics for that particular document. These metrics are used for ordering {@link #search}
-     * results by the {@link SearchSpec#RANKING_STRATEGY_USAGE_COUNT} and
+     * <p>For each call to {@link #reportUsageAsync}, AppSearch updates usage count and usage
+     * recency * metrics for that particular document. These metrics are used for ordering
+     * {@link #search} results by the {@link SearchSpec#RANKING_STRATEGY_USAGE_COUNT} and
      * {@link SearchSpec#RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP} ranking strategies.
      *
      * <p>Reporting usage of a document is optional.
@@ -191,14 +261,27 @@
      *     success.
      */
     @NonNull
-    ListenableFuture<Void> reportUsage(@NonNull ReportUsageRequest request);
+    ListenableFuture<Void> reportUsageAsync(@NonNull ReportUsageRequest request);
+
+    /**
+     * @deprecated use {@link #reportUsageAsync}
+     *
+     * @param request The usage reporting request.
+     * @return The pending result of performing this operation which resolves to {@code null} on
+     *     success.
+     */
+    @NonNull
+    @Deprecated
+    default ListenableFuture<Void> reportUsage(@NonNull ReportUsageRequest request) {
+        return reportUsageAsync(request);
+    }
 
     /**
      * Removes {@link GenericDocument} objects by document IDs in a namespace from the
      * {@link AppSearchSession} database.
      *
      * <p>Removed documents will no longer be surfaced by {@link #search} or
-     * {@link #getByDocumentId}
+     * {@link #getByDocumentIdAsync}
      * calls.
      *
      * <p>Once the database crosses the document count or byte usage threshold, removed documents
@@ -213,10 +296,28 @@
      * {@link AppSearchResult} with a result code of {@link AppSearchResult#RESULT_NOT_FOUND}.
      */
     @NonNull
-    ListenableFuture<AppSearchBatchResult<String, Void>> remove(
+    ListenableFuture<AppSearchBatchResult<String, Void>> removeAsync(
             @NonNull RemoveByDocumentIdRequest request);
 
     /**
+     * @deprecated use {@link #removeAsync}
+     *
+     * @param request {@link RemoveByDocumentIdRequest} with IDs in a namespace to remove from the
+     *                index.
+     * @return a {@link ListenableFuture} which resolves to an {@link AppSearchBatchResult}.
+     * The keys of the {@link AppSearchBatchResult} represent the input IDs from the
+     * {@link RemoveByDocumentIdRequest} object. The values are either {@code null} on success,
+     * or a failed {@link AppSearchResult} otherwise. IDs that are not found will return a failed
+     * {@link AppSearchResult} with a result code of {@link AppSearchResult#RESULT_NOT_FOUND}.
+     */
+    @NonNull
+    @Deprecated
+    default ListenableFuture<AppSearchBatchResult<String, Void>> remove(
+            @NonNull RemoveByDocumentIdRequest request) {
+        return removeAsync(request);
+    }
+
+    /**
      * Removes {@link GenericDocument}s from the index by Query. Documents will be removed if they
      * match the {@code queryExpression} in given namespaces and schemaTypes which is set via
      * {@link SearchSpec.Builder#addFilterNamespaces} and
@@ -234,7 +335,24 @@
      * @return The pending result of performing this operation.
      */
     @NonNull
-    ListenableFuture<Void> remove(@NonNull String queryExpression, @NonNull SearchSpec searchSpec);
+    ListenableFuture<Void> removeAsync(@NonNull String queryExpression,
+            @NonNull SearchSpec searchSpec);
+
+    /**
+     * @deprecated use {@link #removeAsync}
+     *
+     * @param queryExpression Query String to search.
+     * @param searchSpec      Spec containing schemaTypes, namespaces and query expression
+     *                        indicates how document will be removed. All specific about how to
+     *                        scoring, ordering, snippeting and resulting will be ignored.
+     * @return The pending result of performing this operation.
+     */
+    @NonNull
+    @Deprecated
+    default ListenableFuture<Void> remove(@NonNull String queryExpression,
+            @NonNull SearchSpec searchSpec) {
+        return removeAsync(queryExpression, searchSpec);
+    }
 
     /**
      * Gets the storage info for this {@link AppSearchSession} database.
@@ -245,7 +363,18 @@
      * @return a {@link ListenableFuture} which resolves to a {@link StorageInfo} object.
      */
     @NonNull
-    ListenableFuture<StorageInfo> getStorageInfo();
+    ListenableFuture<StorageInfo> getStorageInfoAsync();
+
+    /**
+     * @deprecated use {@link #getStorageInfoAsync()}
+     *
+     * @return a {@link ListenableFuture} which resolves to a {@link StorageInfo} object.
+     */
+    @NonNull
+    @Deprecated
+    default ListenableFuture<StorageInfo> getStorageInfo() {
+        return getStorageInfoAsync();
+    }
 
     /**
      * Flush all schema and document updates, additions, and deletes to disk if possible.
@@ -259,7 +388,21 @@
      * save to disk.
      */
     @NonNull
-    ListenableFuture<Void> requestFlush();
+    ListenableFuture<Void> requestFlushAsync();
+
+    /**
+     * @deprecated use {@link #requestFlushAsync()}
+     *
+     * @return The pending result of performing this operation.
+     * {@link androidx.appsearch.exceptions.AppSearchException} with
+     * {@link AppSearchResult#RESULT_INTERNAL_ERROR} will be set to the future if we hit error when
+     * save to disk.
+     */
+    @NonNull
+    @Deprecated
+    default ListenableFuture<Void> requestFlush() {
+        return requestFlushAsync();
+    }
 
     /**
      * Returns the {@link Features} to check for the availability of certain features
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/Features.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/Features.java
index 26ab787..dc530ee 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/Features.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/Features.java
@@ -24,9 +24,9 @@
  * <p>Features do not depend on any runtime state, and features will never be removed. Once
  * {@link #isFeatureSupported} returns {@code true} for a certain feature, it is safe to assume that
  * the feature will be available forever on that AppSearch storage implementation, at that
- * Android API level, on that device form factor.
- * <!--@exportToFramework:hide-->
+ * Android API level, on that device.
  */
+// @exportToFramework:copyToPath(testing/testutils/src/android/app/appsearch/testutil/external/Features.java)
 public interface Features {
 
     /**
@@ -38,10 +38,35 @@
 
     /**
      * Feature for {@link #isFeatureSupported(String)}. This feature covers
-     * {@link GlobalSearchSession#addObserver} and
-     * {@link GlobalSearchSession#removeObserver}.
+     * {@link GlobalSearchSession#registerObserverCallback} and
+     * {@link GlobalSearchSession#unregisterObserverCallback}.
      */
-    String GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER = "GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER";
+    String GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK =
+            "GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK";
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}. This feature covers
+     * {@link GlobalSearchSession#getSchemaAsync}.
+     */
+    String GLOBAL_SEARCH_SESSION_GET_SCHEMA = "GLOBAL_SEARCH_SESSION_GET_SCHEMA";
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}. This feature covers
+     * {@link GlobalSearchSession#getByDocumentIdAsync}.
+     */
+    String GLOBAL_SEARCH_SESSION_GET_BY_ID = "GLOBAL_SEARCH_SESSION_GET_BY_ID";
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}. This feature covers
+     * {@link SetSchemaRequest.Builder#addAllowedRoleForSchemaTypeVisibility},
+     * {@link SetSchemaRequest.Builder#clearAllowedRolesForSchemaTypeVisibility},
+     * {@link GetSchemaResponse#getSchemaTypesNotDisplayedBySystem()},
+     * {@link GetSchemaResponse#getSchemaTypesVisibleToPackages()},
+     * {@link GetSchemaResponse#getRequiredPermissionsForSchemaTypeVisibility()},
+     * {@link SetSchemaRequest.Builder#addRequiredPermissionsForSchemaTypeVisibility} and
+     * {@link SetSchemaRequest.Builder#clearRequiredPermissionsForSchemaTypeVisibility}
+     */
+    String ADD_PERMISSIONS_AND_GET_VISIBILITY = "ADD_PERMISSIONS_AND_GET_VISIBILITY";
 
     /**
      * Returns whether a feature is supported at run-time. Feature support depends on the
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GenericDocument.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GenericDocument.java
index f1577f7..db06bda 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GenericDocument.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GenericDocument.java
@@ -51,8 +51,8 @@
  * <p>Documents are constructed by using the {@link GenericDocument.Builder}.
  * -->
  *
- * @see AppSearchSession#put
- * @see AppSearchSession#getByDocumentId
+ * @see AppSearchSession#putAsync
+ * @see AppSearchSession#getByDocumentIdAsync
  * @see AppSearchSession#search
  */
 public class GenericDocument {
@@ -81,7 +81,7 @@
      *
      * <p>Indexed properties are properties which are strings where the
      * {@link AppSearchSchema.StringPropertyConfig#getIndexingType} value is anything other
-     * than {@link AppSearchSchema.StringPropertyConfig.IndexingType#INDEXING_TYPE_NONE}.
+     * than {@link AppSearchSchema.StringPropertyConfig#INDEXING_TYPE_NONE}.
      */
     public static int getMaxIndexedProperties() {
         return MAX_INDEXED_PROPERTIES;
@@ -205,7 +205,7 @@
      * time base, the document will be auto-deleted.
      *
      * <p>The default value is 0, which means the document is permanent and won't be auto-deleted
-     * until the app is uninstalled or {@link AppSearchSession#remove} is called.
+     * until the app is uninstalled or {@link AppSearchSession#removeAsync} is called.
      */
     public long getTtlMillis() {
         return mBundle.getLong(TTL_MILLIS_FIELD, DEFAULT_TTL_MILLIS);
@@ -1103,12 +1103,12 @@
          * @param id         the unique identifier for the {@link GenericDocument} in its namespace.
          * @param schemaType the {@link AppSearchSchema} type of the {@link GenericDocument}. The
          *                   provided {@code schemaType} must be defined using
-         *                   {@link AppSearchSession#setSchema} prior
+         *                   {@link AppSearchSession#setSchemaAsync} prior
          *                   to inserting a document of this {@code schemaType} into the
          *                   AppSearch index using
-         *                   {@link AppSearchSession#put}.
+         *                   {@link AppSearchSession#putAsync}.
          *                   Otherwise, the document will be rejected by
-         *                   {@link AppSearchSession#put} with result code
+         *                   {@link AppSearchSession#putAsync} with result code
          *                   {@link AppSearchResult#RESULT_NOT_FOUND}.
          */
         @SuppressWarnings("unchecked")
@@ -1177,7 +1177,7 @@
          * Sets the schema type of this document, changing the value provided in the constructor.
          *
          * <p>To successfully index a document, the schema type must match the name of an
-         * {@link AppSearchSchema} object previously provided to {@link AppSearchSession#setSchema}.
+         * {@link AppSearchSchema} object previously provided to {@link AppSearchSession#setSchemaAsync}.
          * <!--@exportToFramework:hide-->
          */
         @NonNull
@@ -1238,7 +1238,7 @@
          * {@link System#currentTimeMillis} time base, the document will be auto-deleted.
          *
          * <p>The default value is 0, which means the document is permanent and won't be
-         * auto-deleted until the app is uninstalled or {@link AppSearchSession#remove} is
+         * auto-deleted until the app is uninstalled or {@link AppSearchSession#removeAsync} is
          * called.
          *
          * @param ttlMillis a non-negative duration in milliseconds.
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetByDocumentIdRequest.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetByDocumentIdRequest.java
index d9bfc0d..b2ebf3d 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetByDocumentIdRequest.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetByDocumentIdRequest.java
@@ -34,7 +34,7 @@
  * Encapsulates a request to retrieve documents by namespace and IDs from the
  * {@link AppSearchSession} database.
  *
- * @see AppSearchSession#getByDocumentId
+ * @see AppSearchSession#getByDocumentIdAsync
  */
 public final class GetByDocumentIdRequest {
     /**
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetSchemaResponse.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetSchemaResponse.java
index f169099..ef5320d 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetSchemaResponse.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetSchemaResponse.java
@@ -16,21 +16,62 @@
 
 package androidx.appsearch.app;
 
+import android.annotation.SuppressLint;
 import android.os.Bundle;
 
 import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresFeature;
 import androidx.annotation.RestrictTo;
+import androidx.collection.ArrayMap;
 import androidx.collection.ArraySet;
 import androidx.core.util.Preconditions;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
-/** The response class of {@link AppSearchSession#getSchema} */
+/** The response class of {@link AppSearchSession#getSchemaAsync} */
 public final class GetSchemaResponse {
     private static final String VERSION_FIELD = "version";
     private static final String SCHEMAS_FIELD = "schemas";
+    private static final String SCHEMAS_NOT_DISPLAYED_BY_SYSTEM_FIELD =
+            "schemasNotDisplayedBySystem";
+    private static final String SCHEMAS_VISIBLE_TO_PACKAGES_FIELD = "schemasVisibleToPackages";
+    private static final String SCHEMAS_VISIBLE_TO_PERMISSION_FIELD =
+            "schemasVisibleToPermissions";
+    private static final String ALL_REQUIRED_PERMISSION_FIELD =
+            "allRequiredPermission";
+    /**
+     * This Set contains all schemas that are not displayed by the system. All values in the set are
+     * prefixed with the package-database prefix. We do lazy fetch, the object will be created
+     * when the user first time fetch it.
+     */
+    @Nullable
+    private Set<String> mSchemasNotDisplayedBySystem;
+    /**
+     * This map contains all schemas and {@link PackageIdentifier} that has access to the schema.
+     * All keys in the map are prefixed with the package-database prefix. We do lazy fetch, the
+     * object will be created when the user first time fetch it.
+     */
+    @Nullable
+    private Map<String, Set<PackageIdentifier>> mSchemasVisibleToPackages;
+
+    /**
+     * This map contains all schemas and Android Permissions combinations that are required to
+     * access the schema. All keys in the map are prefixed with the package-database prefix. We
+     * do lazy fetch, the object will be created when the user first time fetch it.
+     * The Map is constructed in ANY-ALL cases. The querier could read the {@link GenericDocument}
+     * objects under the {@code schemaType} if they holds ALL required permissions of ANY
+     * combinations.
+     * The value set represents
+     * {@link androidx.appsearch.app.SetSchemaRequest.AppSearchSupportedPermission}.
+     */
+    @Nullable
+    private Map<String, Set<Set<Integer>>> mSchemasVisibleToPermissions;
 
     private final Bundle mBundle;
 
@@ -60,7 +101,7 @@
 
     /**
      * Return the schemas most recently successfully provided to
-     * {@link AppSearchSession#setSchema}.
+     * {@link AppSearchSession#setSchemaAsync}.
      *
      * <p>It is inefficient to call this method repeatedly.
      */
@@ -75,12 +116,160 @@
         return schemas;
     }
 
+    /**
+     * Returns all the schema types that are opted out of being displayed and visible on any
+     * system UI surface.
+     */
+    // @exportToFramework:startStrip()
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+    // @exportToFramework:endStrip()
+    @NonNull
+    public Set<String> getSchemaTypesNotDisplayedBySystem() {
+        checkGetVisibilitySettingSupported();
+        if (mSchemasNotDisplayedBySystem == null) {
+            List<String> schemasNotDisplayedBySystemList =
+                    mBundle.getStringArrayList(SCHEMAS_NOT_DISPLAYED_BY_SYSTEM_FIELD);
+            mSchemasNotDisplayedBySystem =
+                    Collections.unmodifiableSet(new ArraySet<>(schemasNotDisplayedBySystemList));
+        }
+        return mSchemasNotDisplayedBySystem;
+    }
+
+    /**
+     * Returns a mapping of schema types to the set of packages that have access
+     * to that schema type.
+     */
+    // @exportToFramework:startStrip()
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+    // @exportToFramework:endStrip()
+    @NonNull
+    @SuppressWarnings("deprecation")
+    public Map<String, Set<PackageIdentifier>> getSchemaTypesVisibleToPackages() {
+        checkGetVisibilitySettingSupported();
+        if (mSchemasVisibleToPackages == null) {
+            Bundle schemaVisibleToPackagesBundle =
+                    mBundle.getBundle(SCHEMAS_VISIBLE_TO_PACKAGES_FIELD);
+            Map<String, Set<PackageIdentifier>> copy = new ArrayMap<>();
+            for (String key : schemaVisibleToPackagesBundle.keySet()) {
+                List<Bundle> PackageIdentifierBundles = schemaVisibleToPackagesBundle
+                        .getParcelableArrayList(key);
+                Set<PackageIdentifier> packageIdentifiers =
+                        new ArraySet<>(PackageIdentifierBundles.size());
+                for (int i = 0; i < PackageIdentifierBundles.size(); i++) {
+                    packageIdentifiers.add(new PackageIdentifier(PackageIdentifierBundles.get(i)));
+                }
+                copy.put(key, packageIdentifiers);
+            }
+            mSchemasVisibleToPackages = Collections.unmodifiableMap(copy);
+        }
+        return mSchemasVisibleToPackages;
+    }
+
+    /**
+     * Returns a mapping of schema types to the Map of {@link android.Manifest.permission}
+     * combinations that querier must hold to access that schema type.
+     *
+     * <p> The querier could read the {@link GenericDocument} objects under the {@code schemaType}
+     * if they holds ALL required permissions of ANY of the individual value sets.
+     *
+     * <p>For example, if the Map contains {@code {% verbatim %}{{permissionA, PermissionB},
+     * { PermissionC, PermissionD}, {PermissionE}}{% endverbatim %}}.
+     * <ul>
+     *     <li>A querier holds both PermissionA and PermissionB has access.</li>
+     *     <li>A querier holds both PermissionC and PermissionD has access.</li>
+     *     <li>A querier holds only PermissionE has access.</li>
+     *     <li>A querier holds both PermissionA and PermissionE has access.</li>
+     *     <li>A querier holds only PermissionA doesn't have access.</li>
+     *     <li>A querier holds both PermissionA and PermissionC doesn't have access.</li>
+     * </ul>
+     *
+     * @return The map contains schema type and all combinations of required permission for querier
+     *         to access it. The supported Permission are {@link SetSchemaRequest#READ_SMS},
+     *         {@link SetSchemaRequest#READ_CALENDAR}, {@link SetSchemaRequest#READ_CONTACTS},
+     *         {@link SetSchemaRequest#READ_EXTERNAL_STORAGE},
+     *         {@link SetSchemaRequest#READ_HOME_APP_SEARCH_DATA} and
+     *         {@link SetSchemaRequest#READ_ASSISTANT_APP_SEARCH_DATA}.
+     */
+    // @exportToFramework:startStrip()
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+    // @exportToFramework:endStrip()
+    @NonNull
+    @SuppressWarnings("deprecation")
+    public Map<String, Set<Set<Integer>>> getRequiredPermissionsForSchemaTypeVisibility() {
+        checkGetVisibilitySettingSupported();
+        if (mSchemasVisibleToPermissions == null) {
+            Map<String, Set<Set<Integer>>> copy = new ArrayMap<>();
+            Bundle schemaVisibleToPermissionBundle =
+                    mBundle.getBundle(SCHEMAS_VISIBLE_TO_PERMISSION_FIELD);
+            for (String key : schemaVisibleToPermissionBundle.keySet()) {
+                ArrayList<Bundle> allRequiredPermissionsBundle =
+                        schemaVisibleToPermissionBundle.getParcelableArrayList(key);
+                Set<Set<Integer>> visibleToPermissions = new ArraySet<>();
+                if (allRequiredPermissionsBundle != null) {
+                    // This should never be null
+                    for (int i = 0; i < allRequiredPermissionsBundle.size(); i++) {
+                        visibleToPermissions.add(new ArraySet<>(allRequiredPermissionsBundle.get(i)
+                                .getIntegerArrayList(ALL_REQUIRED_PERMISSION_FIELD)));
+                    }
+                }
+                copy.put(key, visibleToPermissions);
+            }
+            mSchemasVisibleToPermissions = Collections.unmodifiableMap(copy);
+        }
+        return mSchemasVisibleToPermissions;
+    }
+
+    private void checkGetVisibilitySettingSupported() {
+        if (!mBundle.containsKey(SCHEMAS_VISIBLE_TO_PACKAGES_FIELD)) {
+            throw new UnsupportedOperationException("Get visibility setting is not supported with"
+                    + " this backend/Android API level combination.");
+        }
+    }
+
     /** Builder for {@link GetSchemaResponse} objects. */
     public static final class Builder {
         private int mVersion = 0;
         private ArrayList<Bundle> mSchemaBundles = new ArrayList<>();
+        /**
+         * Creates the object when we actually set them. If we never set visibility settings, we
+         * should throw {@link UnsupportedOperationException} in the visibility getters.
+         */
+        @Nullable
+        private ArrayList<String> mSchemasNotDisplayedBySystem;
+        private Bundle mSchemasVisibleToPackages;
+        private Bundle mSchemasVisibleToPermissions;
         private boolean mBuilt = false;
 
+        /** Create a {@link Builder} object} */
+        public Builder() {
+            this(/*getVisibilitySettingSupported=*/true);
+        }
+
+        /**
+         * Create a {@link Builder} object}.
+         *
+         * <p>This constructor should only be used in Android API below than T.
+         *
+         * @param getVisibilitySettingSupported whether supported
+         * {@link Features#ADD_PERMISSIONS_AND_GET_VISIBILITY} by this
+         *                                      backend/Android API level.
+         * @hide
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        public Builder(boolean getVisibilitySettingSupported) {
+            if (getVisibilitySettingSupported) {
+                mSchemasNotDisplayedBySystem = new ArrayList<>();
+                mSchemasVisibleToPackages = new Bundle();
+                mSchemasVisibleToPermissions = new Bundle();
+            }
+        }
+
         /**
          * Sets the database overall schema version.
          *
@@ -102,12 +291,130 @@
             return this;
         }
 
+        /**
+         * Sets whether or not documents from the provided {@code schemaType} will be displayed
+         * and visible on any system UI surface.
+         *
+         * @param schemaType The name of an {@link AppSearchSchema} within the same
+         *                   {@link GetSchemaResponse}, which won't be displayed by system.
+         */
+        // Getter getSchemaTypesNotDisplayedBySystem returns plural objects.
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @NonNull
+        public Builder addSchemaTypeNotDisplayedBySystem(@NonNull String schemaType) {
+            Preconditions.checkNotNull(schemaType);
+            resetIfBuilt();
+            if (mSchemasNotDisplayedBySystem == null) {
+                mSchemasNotDisplayedBySystem = new ArrayList<>();
+            }
+            mSchemasNotDisplayedBySystem.add(schemaType);
+            return this;
+        }
+
+        /**
+         * Sets whether or not documents from the provided {@code schemaType} can be read by the
+         * specified package.
+         *
+         * <p>Each package is represented by a {@link PackageIdentifier}, containing a package name
+         * and a byte array of type {@link android.content.pm.PackageManager#CERT_INPUT_SHA256}.
+         *
+         * <p>To opt into one-way data sharing with another application, the developer will need to
+         * explicitly grant the other application’s package name and certificate Read access to its
+         * data.
+         *
+         * <p>For two-way data sharing, both applications need to explicitly grant Read access to
+         * one another.
+         *
+         * @param schemaType               The schema type to set visibility on.
+         * @param packageIdentifiers       Represents the package that has access to the given
+         *                                 schema type.
+         */
+        // Getter getSchemaTypesVisibleToPackages returns a map contains all schema types.
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @NonNull
+        public Builder setSchemaTypeVisibleToPackages(
+                @NonNull String schemaType,
+                @NonNull Set<PackageIdentifier> packageIdentifiers) {
+            Preconditions.checkNotNull(schemaType);
+            Preconditions.checkNotNull(packageIdentifiers);
+            resetIfBuilt();
+            ArrayList<Bundle> bundles = new ArrayList<>(packageIdentifiers.size());
+            for (PackageIdentifier packageIdentifier : packageIdentifiers) {
+                bundles.add(packageIdentifier.getBundle());
+            }
+            mSchemasVisibleToPackages.putParcelableArrayList(schemaType, bundles);
+            return this;
+        }
+
+        /**
+         * Sets a set of required {@link android.Manifest.permission} combinations to the given
+         * schema type.
+         *
+         * <p> The querier could read the {@link GenericDocument} objects under the
+         * {@code schemaType} if they holds ALL required permissions of ANY of the individual value
+         * sets.
+         *
+         * <p>For example, if the Map contains {@code {% verbatim %}{{permissionA, PermissionB},
+         * {PermissionC, PermissionD}, {PermissionE}}{% endverbatim %}}.
+         * <ul>
+         *     <li>A querier holds both PermissionA and PermissionB has access.</li>
+         *     <li>A querier holds both PermissionC and PermissionD has access.</li>
+         *     <li>A querier holds only PermissionE has access.</li>
+         *     <li>A querier holds both PermissionA and PermissionE has access.</li>
+         *     <li>A querier holds only PermissionA doesn't have access.</li>
+         *     <li>A querier holds both PermissionA and PermissionC doesn't have access.</li>
+         * </ul>
+         *
+         * @see android.Manifest.permission#READ_SMS
+         * @see android.Manifest.permission#READ_CALENDAR
+         * @see android.Manifest.permission#READ_CONTACTS
+         * @see android.Manifest.permission#READ_EXTERNAL_STORAGE
+         * @see android.Manifest.permission#READ_HOME_APP_SEARCH_DATA
+         * @see android.Manifest.permission#READ_ASSISTANT_APP_SEARCH_DATA
+         *
+         * @param schemaType             The schema type to set visibility on.
+         * @param visibleToPermissions   The Android permissions that will be required to access
+         *                               the given schema.
+         */
+        // Getter getRequiredPermissionsForSchemaTypeVisibility returns a map for all schemaTypes.
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @NonNull
+        public Builder setRequiredPermissionsForSchemaTypeVisibility(
+                @NonNull String schemaType,
+                @SetSchemaRequest.AppSearchSupportedPermission @NonNull
+                        Set<Set<Integer>> visibleToPermissions) {
+            Preconditions.checkNotNull(schemaType);
+            Preconditions.checkNotNull(visibleToPermissions);
+            resetIfBuilt();
+            ArrayList<Bundle> visibleToPermissionsBundle = new ArrayList<>();
+            for (Set<Integer> allRequiredPermissions : visibleToPermissions) {
+                for (int permission : allRequiredPermissions) {
+                    Preconditions.checkArgumentInRange(permission, SetSchemaRequest.READ_SMS,
+                            SetSchemaRequest.READ_ASSISTANT_APP_SEARCH_DATA, "permission");
+                }
+                Bundle allRequiredPermissionsBundle = new Bundle();
+                allRequiredPermissionsBundle.putIntegerArrayList(
+                        ALL_REQUIRED_PERMISSION_FIELD, new ArrayList<>(allRequiredPermissions));
+                visibleToPermissionsBundle.add(allRequiredPermissionsBundle);
+            }
+            mSchemasVisibleToPermissions.putParcelableArrayList(schemaType,
+                    visibleToPermissionsBundle);
+            return this;
+        }
+
         /** Builds a {@link GetSchemaResponse} object. */
         @NonNull
         public GetSchemaResponse build() {
             Bundle bundle = new Bundle();
             bundle.putInt(VERSION_FIELD, mVersion);
             bundle.putParcelableArrayList(SCHEMAS_FIELD, mSchemaBundles);
+            if (mSchemasNotDisplayedBySystem != null) {
+                // Only save the visibility fields if it was actually set.
+                bundle.putStringArrayList(SCHEMAS_NOT_DISPLAYED_BY_SYSTEM_FIELD,
+                        mSchemasNotDisplayedBySystem);
+                bundle.putBundle(SCHEMAS_VISIBLE_TO_PACKAGES_FIELD, mSchemasVisibleToPackages);
+                bundle.putBundle(SCHEMAS_VISIBLE_TO_PERMISSION_FIELD, mSchemasVisibleToPermissions);
+            }
             mBuilt = true;
             return new GetSchemaResponse(bundle);
         }
@@ -115,6 +422,16 @@
         private void resetIfBuilt() {
             if (mBuilt) {
                 mSchemaBundles = new ArrayList<>(mSchemaBundles);
+                if (mSchemasNotDisplayedBySystem != null) {
+                    // Only reset the visibility fields if it was actually set.
+                    mSchemasNotDisplayedBySystem = new ArrayList<>(mSchemasNotDisplayedBySystem);
+                    Bundle copyVisibleToPackages = new Bundle();
+                    copyVisibleToPackages.putAll(mSchemasVisibleToPackages);
+                    mSchemasVisibleToPackages = copyVisibleToPackages;
+                    Bundle copyVisibleToPermissions = new Bundle();
+                    copyVisibleToPermissions.putAll(mSchemasVisibleToPermissions);
+                    mSchemasVisibleToPermissions = copyVisibleToPermissions;
+                }
                 mBuilt = false;
             }
         }
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GlobalSearchSession.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GlobalSearchSession.java
index 6784803..4ce54b4 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GlobalSearchSession.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GlobalSearchSession.java
@@ -16,9 +16,12 @@
 // @exportToFramework:skipFile()
 package androidx.appsearch.app;
 
+import android.annotation.SuppressLint;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresFeature;
-import androidx.appsearch.observer.AppSearchObserverCallback;
+import androidx.appsearch.exceptions.AppSearchException;
+import androidx.appsearch.observer.ObserverCallback;
 import androidx.appsearch.observer.ObserverSpec;
 
 import com.google.common.util.concurrent.ListenableFuture;
@@ -36,6 +39,31 @@
  */
 public interface GlobalSearchSession extends Closeable {
     /**
+     * Retrieves {@link GenericDocument} documents, belonging to the specified package name and
+     * database name and identified by the namespace and ids in the request, from the
+     * {@link GlobalSearchSession} database. When a call is successful, the result will be
+     * returned in the successes section of the {@link AppSearchBatchResult} object in the callback.
+     * If the package doesn't exist, database doesn't exist, or if the calling package doesn't have
+     * access, these failures will be reflected as {@link AppSearchResult} objects with a
+     * RESULT_NOT_FOUND status code in the failures section of the {@link AppSearchBatchResult}
+     * object.
+     *
+     * @param packageName the name of the package to get from
+     * @param databaseName the name of the database to get from
+     * @param request a request containing a namespace and IDs of the documents to retrieve.
+     */
+    @NonNull
+    // @exportToFramework:startStrip()
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.GLOBAL_SEARCH_SESSION_GET_BY_ID)
+    // @exportToFramework:endStrip()
+    ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentIdAsync(
+            @NonNull String packageName,
+            @NonNull String databaseName,
+            @NonNull GetByDocumentIdRequest request);
+
+    /**
      * Retrieves documents from all AppSearch databases that the querying application has access to.
      *
      * <p>Applications can be granted access to documents by specifying
@@ -51,7 +79,7 @@
      * forming a query string.
      *
      * <p>This method is lightweight. The heavy work will be done in
-     * {@link SearchResults#getNextPage}.
+     * {@link SearchResults#getNextPageAsync}.
      *
      * @param queryExpression query string to search.
      * @param searchSpec      spec for setting document filters, adding projection, setting term
@@ -64,11 +92,11 @@
     /**
      * Reports that a particular document has been used from a system surface.
      *
-     * <p>See {@link AppSearchSession#reportUsage} for a general description of document usage, as
-     * well as an API that can be used by the app itself.
+     * <p>See {@link AppSearchSession#reportUsageAsync} for a general description of document usage,
+     * as well as an API that can be used by the app itself.
      *
      * <p>Usage reported via this method is accounted separately from usage reported via
-     * {@link AppSearchSession#reportUsage} and may be accessed using the constants
+     * {@link AppSearchSession#reportUsageAsync} and may be accessed using the constants
      * {@link SearchSpec#RANKING_STRATEGY_SYSTEM_USAGE_COUNT} and
      * {@link SearchSpec#RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP}.
      *
@@ -79,7 +107,70 @@
      *     is not part of the system.
      */
     @NonNull
-    ListenableFuture<Void> reportSystemUsage(@NonNull ReportSystemUsageRequest request);
+    ListenableFuture<Void> reportSystemUsageAsync(@NonNull ReportSystemUsageRequest request);
+
+    /**
+     * @deprecated use {@link #reportSystemUsageAsync}
+     *
+     * @return The pending result of performing this operation which resolves to {@code null} on
+     *     success. The pending result will be completed with an
+     *     {@link androidx.appsearch.exceptions.AppSearchException} with a code of
+     *     {@link AppSearchResult#RESULT_SECURITY_ERROR} if this API is invoked by an app which
+     *     is not part of the system.
+     */
+    @NonNull
+    @Deprecated
+    default ListenableFuture<Void> reportSystemUsage(@NonNull ReportSystemUsageRequest request) {
+        return reportSystemUsageAsync(request);
+    }
+
+    /**
+     * Retrieves the collection of schemas most recently successfully provided to
+     * {@link AppSearchSession#setSchemaAsync} for any types belonging to the requested package and
+     * database that the caller has been granted access to.
+     *
+     * <p> If the requested package/database combination does not exist or the caller has not been
+     * granted access to it, then an empty GetSchemaResponse will be returned.
+     *
+     *
+     * @param packageName the package that owns the requested {@link AppSearchSchema} instances.
+     * @param databaseName the database that owns the requested {@link AppSearchSchema} instances.
+     * @return The pending {@link GetSchemaResponse} containing the schemas that the caller has
+     * access to or an empty GetSchemaResponse if the request package and database does not
+     * exist, has not set a schema or contains no schemas that are accessible to the caller.
+     */
+    // This call hits disk; async API prevents us from treating these calls as properties.
+    @SuppressLint("KotlinPropertyAccess")
+    @NonNull
+    // @exportToFramework:startStrip()
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA)
+    // @exportToFramework:endStrip()
+    ListenableFuture<GetSchemaResponse> getSchemaAsync(@NonNull String packageName,
+            @NonNull String databaseName);
+
+    /**
+     * @deprecated use {@link #getSchemaAsync}.
+     *
+     * @param packageName the package that owns the requested {@link AppSearchSchema} instances.
+     * @param databaseName the database that owns the requested {@link AppSearchSchema} instances.
+     * @return The pending {@link GetSchemaResponse} containing the schemas that the caller has
+     * access to or an empty GetSchemaResponse if the request package and database does not
+     * exist, has not set a schema or contains no schemas that are accessible to the caller.
+     */
+    @SuppressLint("KotlinPropertyAccess")
+    @NonNull
+    // @exportToFramework:startStrip()
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA)
+    // @exportToFramework:endStrip()
+    @Deprecated
+    default ListenableFuture<GetSchemaResponse> getSchema(@NonNull String packageName,
+            @NonNull String databaseName) {
+        return getSchemaAsync(packageName, databaseName);
+    }
 
     /**
      * Returns the {@link Features} to check for the availability of certain features
@@ -89,63 +180,75 @@
     Features getFeatures();
 
     /**
-     * Adds an {@link AppSearchObserverCallback} to monitor changes within the
-     * databases owned by {@code observedPackage} if they match the given
+     * Adds an {@link ObserverCallback} to monitor changes within the databases owned by
+     * {@code targetPackageName} if they match the given
      * {@link androidx.appsearch.observer.ObserverSpec}.
      *
-     * <p>If the data owned by {@code observedPackage} is not visible to you, the registration call
-     * will succeed but no notifications will be dispatched. Notifications could start flowing later
-     * if {@code observedPackage} changes its schema visibility settings.
+     * <p>The observer callback is only triggered for data that changes after it is registered. No
+     * notification about existing data is sent as a result of registering an observer. To find out
+     * about existing data, you must use the {@link GlobalSearchSession#search} API.
      *
-     * <p>If no package matching {@code observedPackage} exists on the system, the registration call
-     * will succeed but no notifications will be dispatched. Notifications could start flowing later
-     * if {@code observedPackage} is installed and starts indexing data.
+     * <p>If the data owned by {@code targetPackageName} is not visible to you, the registration
+     * call will succeed but no notifications will be dispatched. Notifications could start flowing
+     * later if {@code targetPackageName} changes its schema visibility settings.
+     *
+     * <p>If no package matching {@code targetPackageName} exists on the system, the registration
+     * call will succeed but no notifications will be dispatched. Notifications could start flowing
+     * later if {@code targetPackageName} is installed and starts indexing data.
      *
      * <p>This feature may not be available in all implementations. Check
-     * {@link Features#GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER} before calling this method.
+     * {@link Features#GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK} before calling this method.
      *
-     * @param observedPackage Package whose changes to monitor
+     * @param targetPackageName Package whose changes to monitor
      * @param spec            Specification of what types of changes to listen for
      * @param executor        Executor on which to call the {@code observer} callback methods.
      * @param observer        Callback to trigger when a schema or document changes
+     * @throws AppSearchException            if an error occurs trying to register the observer
      * @throws UnsupportedOperationException if this feature is not available on this
      *                                       AppSearch implementation.
      */
     // @exportToFramework:startStrip()
     @RequiresFeature(
             enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
-            name = Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER)
+            name = Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK)
     // @exportToFramework:endStrip()
-    void addObserver(
-            @NonNull String observedPackage,
+    void registerObserverCallback(
+            @NonNull String targetPackageName,
             @NonNull ObserverSpec spec,
             @NonNull Executor executor,
-            @NonNull AppSearchObserverCallback observer);
+            @NonNull ObserverCallback observer) throws AppSearchException;
 
     /**
-     * Removes previously registered {@link AppSearchObserverCallback} instances from the system.
+     * Removes previously registered {@link ObserverCallback} instances from the system.
      *
-     * <p>All instances of {@link AppSearchObserverCallback} which are equal to the provided
-     * callback using {@link AppSearchObserverCallback#equals} will be removed.
+     * <p>All instances of {@link ObserverCallback} which are registered to observe
+     * {@code targetPackageName} and compare equal to the provided callback using the provided
+     * argument's {@link ObserverCallback#equals} will be removed.
      *
      * <p>If no matching observers have been registered, this method has no effect. If multiple
      * matching observers have been registered, all will be removed.
      *
      * <p>This feature may not be available in all implementations. Check
-     * {@link Features#GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER} before calling this method.
+     * {@link Features#GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK} before calling this method.
      *
-     * @param observedPackage Package in which the observers to be removed are registered
-     * @param observer        Callback to unregister
+     * @param targetPackageName Package which the observers to be removed are listening to.
+     * @param observer          Callback to unregister.
+     * @throws AppSearchException            if an error occurs trying to remove the observer, such
+     *                                       as a failure to communicate with the system service
+     *                                       in the platform backend. Note that no
+     *                                       error will be thrown if the provided observer
+     *                                       doesn't match any registered observer.
      * @throws UnsupportedOperationException if this feature is not available on this
      *                                       AppSearch implementation.
      */
     // @exportToFramework:startStrip()
     @RequiresFeature(
             enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
-            name = Features.GLOBAL_SEARCH_SESSION_ADD_REMOVE_OBSERVER)
+            name = Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK)
     // @exportToFramework:endStrip()
-    void removeObserver(
-            @NonNull String observedPackage, @NonNull AppSearchObserverCallback observer);
+    void unregisterObserverCallback(
+            @NonNull String targetPackageName, @NonNull ObserverCallback observer)
+            throws AppSearchException;
 
     /** Closes the {@link GlobalSearchSession}. */
     @Override
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/Migrator.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/Migrator.java
index b47735b..e6a7b2c 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/Migrator.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/Migrator.java
@@ -51,11 +51,11 @@
      * higher version number than the current {@link AppSearchSchema} saved in AppSearch.
      *
      * <p>If this {@link Migrator} is provided to cover a compatible schema change via
-     * {@link AppSearchSession#setSchema}, documents under the old version won't be removed
+     * {@link AppSearchSession#setSchemaAsync}, documents under the old version won't be removed
      * unless you use the same document ID.
      *
      * <p>This method will be invoked on the background worker thread provided via
-     * {@link AppSearchSession#setSchema}.
+     * {@link AppSearchSession#setSchemaAsync}.
      *
      * @param currentVersion The current version of the document's schema.
      * @param finalVersion  The final version that documents need to be migrated to.
@@ -74,7 +74,7 @@
      * lower version number than the current {@link AppSearchSchema} saved in AppSearch.
      *
      * <p>If this {@link Migrator} is provided to cover a compatible schema change via
-     * {@link AppSearchSession#setSchema}, documents under the old version won't be removed
+     * {@link AppSearchSession#setSchemaAsync}, documents under the old version won't be removed
      * unless you use the same document ID.
      *
      * <p>This method will be invoked on the background worker thread.
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/PutDocumentsRequest.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/PutDocumentsRequest.java
index 4d4a000..dff69b2 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/PutDocumentsRequest.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/PutDocumentsRequest.java
@@ -37,7 +37,7 @@
  * {@link GenericDocument}.
  * <!--@exportToFramework:else()-->
  *
- * @see AppSearchSession#put
+ * @see AppSearchSession#putAsync
  */
 public final class PutDocumentsRequest {
     private final List<GenericDocument> mDocuments;
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/RemoveByDocumentIdRequest.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/RemoveByDocumentIdRequest.java
index addb96a..38be17a 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/RemoveByDocumentIdRequest.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/RemoveByDocumentIdRequest.java
@@ -29,7 +29,7 @@
  * Encapsulates a request to remove documents by namespace and IDs from the
  * {@link AppSearchSession} database.
  *
- * @see AppSearchSession#remove
+ * @see AppSearchSession#removeAsync
  */
 public final class RemoveByDocumentIdRequest {
     private final String mNamespace;
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportSystemUsageRequest.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportSystemUsageRequest.java
index db26931..12422eb 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportSystemUsageRequest.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportSystemUsageRequest.java
@@ -23,9 +23,9 @@
  * A request to report usage of a document owned by another app from a system UI surface.
  *
  * <p>Usage reported in this way is measured separately from usage reported via
- * {@link AppSearchSession#reportUsage}.
+ * {@link AppSearchSession#reportUsageAsync}.
  *
- * <p>See {@link GlobalSearchSession#reportSystemUsage} for a detailed description of usage
+ * <p>See {@link GlobalSearchSession#reportSystemUsageAsync} for a detailed description of usage
  * reporting.
  */
 public final class ReportSystemUsageRequest {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportUsageRequest.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportUsageRequest.java
index 25edaf4..14b70c7 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportUsageRequest.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportUsageRequest.java
@@ -22,9 +22,9 @@
 /**
  * A request to report usage of a document.
  *
- * <p>See {@link AppSearchSession#reportUsage} for a detailed description of usage reporting.
+ * <p>See {@link AppSearchSession#reportUsageAsync} for a detailed description of usage reporting.
  *
- * @see AppSearchSession#reportUsage
+ * @see AppSearchSession#reportUsageAsync
  */
 public final class ReportUsageRequest {
     private final String mNamespace;
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResult.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResult.java
index 7350991..17ed1266 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResult.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResult.java
@@ -268,52 +268,68 @@
     }
 
     /**
-     * This class represents a match objects for any Snippets that might be present in
-     * {@link SearchResults} from query. Using this class
-     * user can get the full text, exact matches and Snippets of document content for a given match.
+     * This class represents match objects for any Snippets that might be present in
+     * {@link SearchResults} from a query. Using this class, the user can get:
+     * <ul>
+     *     <li>the full text - all of the text in that String property</li>
+     *     <li>the exact term match - the 'term' (full word) that matched the query</li>
+     *     <li>the subterm match - the portion of the matched term that appears in the query</li>
+     *     <li>a suggested text snippet - a portion of the full text surrounding the exact term
+     *     match, set to term boundaries. The size of the snippet is specified in
+     *     {@link SearchSpec.Builder#setMaxSnippetSize}</li>
+     * </ul>
+     * for each match in the document.
      *
      * <p>Class Example 1:
-     * A document contains following text in property subject:
-     * <p>A commonly used fake word is foo. Another nonsense word that’s used a lot is bar.
+     * <p>A document contains the following text in property "subject":
+     * <p>"A commonly used fake word is foo. Another nonsense word that’s used a lot is bar."
      *
-     * <p>If the queryExpression is "foo".
-     *
-     * <p>{@link MatchInfo#getPropertyPath()} returns "subject"
-     * <p>{@link MatchInfo#getFullText()} returns "A commonly used fake word is foo. Another
-     * nonsense word that’s used a lot is bar."
-     * <p>{@link MatchInfo#getExactMatchRange()} returns [29, 32]
-     * <p>{@link MatchInfo#getExactMatch()} returns "foo"
-     * <p>{@link MatchInfo#getSubmatchRange()} returns [29, 32]
-     * <p>{@link MatchInfo#getSubmatch()} returns "foo"
-     * <p>{@link MatchInfo#getSnippetRange()} returns [26, 33]
-     * <p>{@link MatchInfo#getSnippet()} returns "is foo."
+     * <p>If the queryExpression is "foo" and {@link SearchSpec#getMaxSnippetSize}  is 10,
+     * <ul>
+     *      <li>{@link MatchInfo#getPropertyPath()} returns "subject"</li>
+     *      <li>{@link MatchInfo#getFullText()} returns "A commonly used fake word is foo. Another
+     * nonsense word that’s used a lot is bar."</li>
+     *      <li>{@link MatchInfo#getExactMatchRange()} returns [29, 32]</li>
+     *      <li>{@link MatchInfo#getExactMatch()} returns "foo"</li>
+     *      <li>{@link MatchInfo#getSubmatchRange()} returns [29, 32]</li>
+     *      <li>{@link MatchInfo#getSubmatch()} returns "foo"</li>
+     *      <li>{@link MatchInfo#getSnippetRange()} returns [26, 33]</li>
+     *      <li>{@link MatchInfo#getSnippet()} returns "is foo."</li>
+     * </ul>
      * <p>
      * <p>Class Example 2:
-     * A document contains a property name sender which contains 2 property names name and email, so
-     * we will have 2 property paths: {@code sender.name} and {@code sender.email}.
-     * <p>Let {@code sender.name = "Test Name Jr."} and
-     * {@code sender.email = "[email protected]"}
+     * <p>A document contains one property named "subject" and one property named "sender" which
+     * contains a "name" property.
      *
-     * <p>If the queryExpression is "Test". We will have 2 matches.
+     * In this case, we will have 2 property paths: {@code sender.name} and {@code subject}.
+     * <p>Let {@code sender.name = "Test Name Jr."} and
+     * {@code subject = "Testing 1 2 3"}
+     *
+     * <p>If the queryExpression is "Test" with {@link SearchSpec#TERM_MATCH_PREFIX} and
+     * {@link SearchSpec#getMaxSnippetSize} is 10. We will have 2 matches:
      *
      * <p> Match-1
-     * <p>{@link MatchInfo#getPropertyPath()} returns "sender.name"
-     * <p>{@link MatchInfo#getFullText()} returns "Test Name Jr."
-     * <p>{@link MatchInfo#getExactMatchRange()} returns [0, 4]
-     * <p>{@link MatchInfo#getExactMatch()} returns "Test"
-     * <p>{@link MatchInfo#getSubmatchRange()} returns [0, 4]
-     * <p>{@link MatchInfo#getSubmatch()} returns "Test"
-     * <p>{@link MatchInfo#getSnippetRange()} returns [0, 9]
-     * <p>{@link MatchInfo#getSnippet()} returns "Test Name"
+     * <ul>
+     *      <li>{@link MatchInfo#getPropertyPath()} returns "sender.name"</li>
+     *      <li>{@link MatchInfo#getFullText()} returns "Test Name Jr."</li>
+     *      <li>{@link MatchInfo#getExactMatchRange()} returns [0, 4]</li>
+     *      <li>{@link MatchInfo#getExactMatch()} returns "Test"</li>
+     *      <li>{@link MatchInfo#getSubmatchRange()} returns [0, 4]</li>
+     *      <li>{@link MatchInfo#getSubmatch()} returns "Test"</li>
+     *      <li>{@link MatchInfo#getSnippetRange()} returns [0, 9]</li>
+     *      <li>{@link MatchInfo#getSnippet()} returns "Test Name"</li>
+     * </ul>
      * <p> Match-2
-     * <p>{@link MatchInfo#getPropertyPath()} returns "sender.email"
-     * <p>{@link MatchInfo#getFullText()} returns "[email protected]"
-     * <p>{@link MatchInfo#getExactMatchRange()} returns [0, 20]
-     * <p>{@link MatchInfo#getExactMatch()} returns "[email protected]"
-     * <p>{@link MatchInfo#getSubmatchRange()} returns [0, 4]
-     * <p>{@link MatchInfo#getSubmatch()} returns "Test"
-     * <p>{@link MatchInfo#getSnippetRange()} returns [0, 20]
-     * <p>{@link MatchInfo#getSnippet()} returns "[email protected]"
+     * <ul>
+     *      <li>{@link MatchInfo#getPropertyPath()} returns "subject"</li>
+     *      <li>{@link MatchInfo#getFullText()} returns "Testing 1 2 3"</li>
+     *      <li>{@link MatchInfo#getExactMatchRange()} returns [0, 7]</li>
+     *      <li>{@link MatchInfo#getExactMatch()} returns "Testing"</li>
+     *      <li>{@link MatchInfo#getSubmatchRange()} returns [0, 4]</li>
+     *      <li>{@link MatchInfo#getSubmatch()} returns "Test"</li>
+     *      <li>{@link MatchInfo#getSnippetRange()} returns [0, 9]</li>
+     *      <li>{@link MatchInfo#getSnippet()} returns "Testing 1"</li>
+     * </ul>
      */
     public static final class MatchInfo {
         /** The path of the matching snippet property. */
@@ -378,8 +394,10 @@
 
         /**
          * Gets the full text corresponding to the given entry.
-         * <p>For class example this returns "A commonly used fake word is foo. Another nonsense
+         * <p>Class example 1: this returns "A commonly used fake word is foo. Another nonsense
          * word that's used a lot is bar."
+         * <p>Class example 2: for the first {@link MatchInfo}, this returns "Test Name Jr." and,
+         * for the second {@link MatchInfo}, this returns "Testing 1 2 3".
          */
         @NonNull
         public String getFullText() {
@@ -396,7 +414,7 @@
          * Gets the {@link MatchRange} of the exact term of the given entry that matched the query.
          * <p>Class example 1: this returns [29, 32].
          * <p>Class example 2: for the first {@link MatchInfo}, this returns [0, 4] and, for the
-         * second {@link MatchInfo}, this returns [0, 20].
+         * second {@link MatchInfo}, this returns [0, 7].
          */
         @NonNull
         public MatchRange getExactMatchRange() {
@@ -412,7 +430,7 @@
          * Gets the exact term of the given entry that matched the query.
          * <p>Class example 1: this returns "foo".
          * <p>Class example 2: for the first {@link MatchInfo}, this returns "Test" and, for the
-         * second {@link MatchInfo}, this returns "[email protected]".
+         * second {@link MatchInfo}, this returns "Testing".
          */
         @NonNull
         public CharSequence getExactMatch() {
@@ -481,7 +499,7 @@
          * {@link SearchSpec.Builder#setMaxSnippetSize}.
          * <p>Class example 1: this returns [29, 41].
          * <p>Class example 2: for the first {@link MatchInfo}, this returns [0, 9] and, for the
-         * second {@link MatchInfo}, this returns [0, 20].
+         * second {@link MatchInfo}, this returns [0, 13].
          */
         @NonNull
         public MatchRange getSnippetRange() {
@@ -501,7 +519,7 @@
          * the matched token with content on either side clipped to token boundaries.
          * <p>Class example 1: this returns "foo. Another".
          * <p>Class example 2: for the first {@link MatchInfo}, this returns "Test Name" and, for
-         * the second {@link MatchInfo}, this returns "[email protected]".
+         * the second {@link MatchInfo}, this returns "Testing 1 2 3".
          */
         @NonNull
         public CharSequence getSnippet() {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResults.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResults.java
index 6bf301f..23b6b5d 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResults.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResults.java
@@ -30,7 +30,7 @@
  * objects, referred to as a "page", limited by the size configured by
  * {@link SearchSpec.Builder#setResultCountPerPage}.
  *
- * <p>To fetch a page of results, call {@link #getNextPage()}.
+ * <p>To fetch a page of results, call {@link #getNextPageAsync()}.
  *
  * <p>All instances of {@link SearchResults} must call {@link SearchResults#close()} after the
  * results are fetched.
@@ -50,7 +50,18 @@
      * objects.
      */
     @NonNull
-    ListenableFuture<List<SearchResult>> getNextPage();
+    ListenableFuture<List<SearchResult>> getNextPageAsync();
+
+    /**
+     * @deprecated use {@link #getNextPageAsync}.
+     * @return a {@link ListenableFuture} which resolves to a list of {@link SearchResult}
+     * objects.
+     */
+    @NonNull
+    @Deprecated
+    default ListenableFuture<List<SearchResult>> getNextPage() {
+        return getNextPageAsync();
+    }
 
     @Override
     void close();
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaRequest.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaRequest.java
index e09eec9..52e953a 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaRequest.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaRequest.java
@@ -18,14 +18,18 @@
 
 import android.annotation.SuppressLint;
 
+import androidx.annotation.IntDef;
 import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
+import androidx.annotation.RequiresFeature;
 import androidx.annotation.RestrictTo;
 import androidx.appsearch.exceptions.AppSearchException;
 import androidx.collection.ArrayMap;
 import androidx.collection.ArraySet;
 import androidx.core.util.Preconditions;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -76,13 +80,105 @@
  *         will be set into both {@link SetSchemaResponse#getIncompatibleTypes()} and
  *         {@link SetSchemaResponse#getMigratedTypes()}. See the migration section below.
  * </ul>
- * @see AppSearchSession#setSchema
+ * @see AppSearchSession#setSchemaAsync
  * @see Migrator
  */
 public final class SetSchemaRequest {
+
+    /**
+     * List of Android Permission are supported in
+     * {@link SetSchemaRequest.Builder#addRequiredPermissionsForSchemaTypeVisibility}
+     *
+     * @see android.Manifest.permission
+     * @hide
+     */
+    @IntDef(value = {
+            READ_SMS,
+            READ_CALENDAR,
+            READ_CONTACTS,
+            READ_EXTERNAL_STORAGE,
+            READ_HOME_APP_SEARCH_DATA,
+            READ_ASSISTANT_APP_SEARCH_DATA,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    // @exportToFramework:startStrip()
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+    // @exportToFramework:endStrip()
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public @interface AppSearchSupportedPermission {}
+
+    /**
+     * The {@link android.Manifest.permission#READ_SMS} AppSearch supported in
+     * {@link SetSchemaRequest.Builder#addRequiredPermissionsForSchemaTypeVisibility}
+     */
+    // @exportToFramework:startStrip()
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+    // @exportToFramework:endStrip()
+    public static final int READ_SMS = 1;
+
+    /**
+     * The {@link android.Manifest.permission#READ_CALENDAR} AppSearch supported in
+     * {@link SetSchemaRequest.Builder#addRequiredPermissionsForSchemaTypeVisibility}
+     */
+    // @exportToFramework:startStrip()
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+    // @exportToFramework:endStrip()
+    public static final int READ_CALENDAR = 2;
+
+    /**
+     * The {@link android.Manifest.permission#READ_CONTACTS} AppSearch supported in
+     * {@link SetSchemaRequest.Builder#addRequiredPermissionsForSchemaTypeVisibility}
+     */
+    // @exportToFramework:startStrip()
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+    // @exportToFramework:endStrip()
+    public static final int READ_CONTACTS = 3;
+
+    /**
+     * The {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} AppSearch supported in
+     * {@link SetSchemaRequest.Builder#addRequiredPermissionsForSchemaTypeVisibility}
+     */
+    // @exportToFramework:startStrip()
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+    // @exportToFramework:endStrip()
+    public static final int READ_EXTERNAL_STORAGE = 4;
+
+    /**
+     * The {@link android.Manifest.permission#READ_HOME_APP_SEARCH_DATA} AppSearch supported in
+     * {@link SetSchemaRequest.Builder#addRequiredPermissionsForSchemaTypeVisibility}
+     */
+    // @exportToFramework:startStrip()
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+    // @exportToFramework:endStrip()
+    public static final int READ_HOME_APP_SEARCH_DATA = 5;
+
+    /**
+     * The {@link android.Manifest.permission#READ_ASSISTANT_APP_SEARCH_DATA} AppSearch supported in
+     * {@link SetSchemaRequest.Builder#addRequiredPermissionsForSchemaTypeVisibility}
+     */
+    // @exportToFramework:startStrip()
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+    // @exportToFramework:endStrip()
+    public static final int READ_ASSISTANT_APP_SEARCH_DATA = 6;
+
     private final Set<AppSearchSchema> mSchemas;
     private final Set<String> mSchemasNotDisplayedBySystem;
     private final Map<String, Set<PackageIdentifier>> mSchemasVisibleToPackages;
+    private final Map<String, Set<Set<Integer>>> mSchemasVisibleToPermissions;
     private final Map<String, Migrator> mMigrators;
     private final boolean mForceOverride;
     private final int mVersion;
@@ -90,12 +186,14 @@
     SetSchemaRequest(@NonNull Set<AppSearchSchema> schemas,
             @NonNull Set<String> schemasNotDisplayedBySystem,
             @NonNull Map<String, Set<PackageIdentifier>> schemasVisibleToPackages,
+            @NonNull Map<String, Set<Set<Integer>>> schemasVisibleToPermissions,
             @NonNull Map<String, Migrator> migrators,
             boolean forceOverride,
             int version) {
         mSchemas = Preconditions.checkNotNull(schemas);
         mSchemasNotDisplayedBySystem = Preconditions.checkNotNull(schemasNotDisplayedBySystem);
         mSchemasVisibleToPackages = Preconditions.checkNotNull(schemasVisibleToPackages);
+        mSchemasVisibleToPermissions = Preconditions.checkNotNull(schemasVisibleToPermissions);
         mMigrators = Preconditions.checkNotNull(migrators);
         mForceOverride = forceOverride;
         mVersion = version;
@@ -125,13 +223,46 @@
     @NonNull
     public Map<String, Set<PackageIdentifier>> getSchemasVisibleToPackages() {
         Map<String, Set<PackageIdentifier>> copy = new ArrayMap<>();
-        for (String key : mSchemasVisibleToPackages.keySet()) {
-            copy.put(key, new ArraySet<>(mSchemasVisibleToPackages.get(key)));
+        for (Map.Entry<String, Set<PackageIdentifier>> entry :
+                mSchemasVisibleToPackages.entrySet()) {
+            copy.put(entry.getKey(), new ArraySet<>(entry.getValue()));
         }
         return copy;
     }
 
     /**
+     * Returns a mapping of schema types to the Map of {@link android.Manifest.permission}
+     * combinations that querier must hold to access that schema type.
+     *
+     * <p> The querier could read the {@link GenericDocument} objects under the {@code schemaType}
+     * if they holds ALL required permissions of ANY of the individual value sets.
+     *
+     * <p>For example, if the Map contains {@code {% verbatim %}{{permissionA, PermissionB},
+     * {PermissionC, PermissionD}, {PermissionE}}{% endverbatim %}}.
+     * <ul>
+     *     <li>A querier holds both PermissionA and PermissionB has access.</li>
+     *     <li>A querier holds both PermissionC and PermissionD has access.</li>
+     *     <li>A querier holds only PermissionE has access.</li>
+     *     <li>A querier holds both PermissionA and PermissionE has access.</li>
+     *     <li>A querier holds only PermissionA doesn't have access.</li>
+     *     <li>A querier holds both PermissionA and PermissionC doesn't have access.</li>
+     * </ul>
+     *
+     * <p>It’s inefficient to call this method repeatedly.
+     *
+     * @return The map contains schema type and all combinations of required permission for querier
+     *         to access it. The supported Permission are {@link SetSchemaRequest#READ_SMS},
+     *         {@link SetSchemaRequest#READ_CALENDAR}, {@link SetSchemaRequest#READ_CONTACTS},
+     *         {@link SetSchemaRequest#READ_EXTERNAL_STORAGE},
+     *         {@link SetSchemaRequest#READ_HOME_APP_SEARCH_DATA} and
+     *         {@link SetSchemaRequest#READ_ASSISTANT_APP_SEARCH_DATA}.
+     */
+    @NonNull
+    public Map<String, Set<Set<Integer>>> getRequiredPermissionsForSchemaTypeVisibility() {
+        return deepCopy(mSchemasVisibleToPermissions);
+    }
+
+    /**
      * Returns the map of {@link Migrator}, the key will be the schema type of the
      * {@link Migrator} associated with.
      */
@@ -174,6 +305,7 @@
         private ArraySet<String> mSchemasNotDisplayedBySystem = new ArraySet<>();
         private ArrayMap<String, Set<PackageIdentifier>> mSchemasVisibleToPackages =
                 new ArrayMap<>();
+        private ArrayMap<String, Set<Set<Integer>>> mSchemasVisibleToPermissions = new ArrayMap<>();
         private ArrayMap<String, Migrator> mMigrators = new ArrayMap<>();
         private boolean mForceOverride = false;
         private int mVersion = DEFAULT_VERSION;
@@ -255,7 +387,7 @@
          * and visible on any system UI surface.
          *
          * <p>This setting applies to the provided {@code schemaType} only, and does not persist
-         * across {@link AppSearchSession#setSchema} calls.
+         * across {@link AppSearchSession#setSchemaAsync} calls.
          *
          * <p>The default behavior, if this method is not called, is to allow types to be
          * displayed on system UI surfaces.
@@ -280,6 +412,72 @@
         }
 
         /**
+         * Adds a set of required Android {@link android.Manifest.permission} combination to the
+         * given schema type.
+         *
+         * <p> If the querier holds ALL of the required permissions in this combination, they will
+         * have access to read {@link GenericDocument} objects of the given schema type.
+         *
+         * <p> You can call this method to add multiple permission combinations, and the querier
+         * will have access if they holds ANY of the combinations.
+         *
+         * <p>The supported Permissions are {@link #READ_SMS}, {@link #READ_CALENDAR},
+         * {@link #READ_CONTACTS}, {@link #READ_EXTERNAL_STORAGE},
+         * {@link #READ_HOME_APP_SEARCH_DATA} and {@link #READ_ASSISTANT_APP_SEARCH_DATA}.
+         *
+         * @see android.Manifest.permission#READ_SMS
+         * @see android.Manifest.permission#READ_CALENDAR
+         * @see android.Manifest.permission#READ_CONTACTS
+         * @see android.Manifest.permission#READ_EXTERNAL_STORAGE
+         * @see android.Manifest.permission#READ_HOME_APP_SEARCH_DATA
+         * @see android.Manifest.permission#READ_ASSISTANT_APP_SEARCH_DATA
+         * @param schemaType       The schema type to set visibility on.
+         * @param permissions      A set of required Android permissions the caller need to hold
+         *                         to access {@link GenericDocument} objects that under the given
+         *                         schema.
+         * @throws IllegalArgumentException – if input unsupported permission.
+         */
+        // Merged list available from getRequiredPermissionsForSchemaTypeVisibility
+        @SuppressLint("MissingGetterMatchingBuilder")
+        // @exportToFramework:startStrip()
+        @RequiresFeature(
+                enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+                name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+        // @exportToFramework:endStrip()
+        @NonNull
+        public Builder addRequiredPermissionsForSchemaTypeVisibility(@NonNull String schemaType,
+                @AppSearchSupportedPermission @NonNull Set<Integer> permissions) {
+            Preconditions.checkNotNull(schemaType);
+            Preconditions.checkNotNull(permissions);
+            for (int permission : permissions) {
+                Preconditions.checkArgumentInRange(permission, READ_SMS,
+                        READ_ASSISTANT_APP_SEARCH_DATA, "permission");
+            }
+            resetIfBuilt();
+            Set<Set<Integer>> visibleToPermissions = mSchemasVisibleToPermissions.get(schemaType);
+            if (visibleToPermissions == null) {
+                visibleToPermissions = new ArraySet<>();
+                mSchemasVisibleToPermissions.put(schemaType, visibleToPermissions);
+            }
+            visibleToPermissions.add(permissions);
+            return this;
+        }
+
+        /**  Clears all required permissions combinations for the given schema type.  */
+        // @exportToFramework:startStrip()
+        @RequiresFeature(
+                enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+                name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+        // @exportToFramework:endStrip()
+        @NonNull
+        public Builder clearRequiredPermissionsForSchemaTypeVisibility(@NonNull String schemaType) {
+            Preconditions.checkNotNull(schemaType);
+            resetIfBuilt();
+            mSchemasVisibleToPermissions.remove(schemaType);
+            return this;
+        }
+
+        /**
          * Sets whether or not documents from the provided {@code schemaType} can be read by the
          * specified package.
          *
@@ -353,7 +551,7 @@
          *
          * @see SetSchemaRequest.Builder#setVersion
          * @see SetSchemaRequest.Builder#addSchemas
-         * @see AppSearchSession#setSchema
+         * @see AppSearchSession#setSchemaAsync
          */
         @NonNull
         @SuppressLint("MissingGetterMatchingBuilder")        // Getter return plural objects.
@@ -388,7 +586,7 @@
          *
          * @see SetSchemaRequest.Builder#setVersion
          * @see SetSchemaRequest.Builder#addSchemas
-         * @see AppSearchSession#setSchema
+         * @see AppSearchSession#setSchemaAsync
          */
         @NonNull
         public Builder setMigrators(@NonNull Map<String, Migrator> migrators) {
@@ -406,7 +604,7 @@
          * visible on any system UI surface.
          *
          * <p>This setting applies to the provided {@link androidx.appsearch.annotation.Document}
-         * annotated class only, and does not persist across {@link AppSearchSession#setSchema}
+         * annotated class only, and does not persist across {@link AppSearchSession#setSchemaAsync}
          * calls.
          *
          * <p>The default behavior, if this method is not called, is to allow types to be
@@ -469,6 +667,66 @@
             return setSchemaTypeVisibilityForPackage(factory.getSchemaName(), visible,
                     packageIdentifier);
         }
+
+        /**
+         * Adds a set of required Android {@link android.Manifest.permission} combination to the
+         * given schema type.
+         *
+         * <p> If the querier holds ALL of the required permissions in this combination, they will
+         * have access to read {@link GenericDocument} objects of the given schema type.
+         *
+         * <p> You can call this method to add multiple permission combinations, and the querier
+         * will have access if they holds ANY of the combinations.
+         *
+         * <p>The supported Permissions are {@link #READ_SMS}, {@link #READ_CALENDAR},
+         * {@link #READ_CONTACTS}, {@link #READ_EXTERNAL_STORAGE},
+         * {@link #READ_HOME_APP_SEARCH_DATA} and {@link #READ_ASSISTANT_APP_SEARCH_DATA}.
+         *
+         * @see android.Manifest.permission#READ_SMS
+         * @see android.Manifest.permission#READ_CALENDAR
+         * @see android.Manifest.permission#READ_CONTACTS
+         * @see android.Manifest.permission#READ_EXTERNAL_STORAGE
+         * @see android.Manifest.permission#READ_HOME_APP_SEARCH_DATA
+         * @see android.Manifest.permission#READ_ASSISTANT_APP_SEARCH_DATA
+         * @param documentClass    The {@link androidx.appsearch.annotation.Document} class to set
+         *                         visibility on.
+         * @param permissions      A set of required Android permissions the caller need to hold
+         *                         to access {@link GenericDocument} objects that under the given
+         *                         schema.
+         * @throws IllegalArgumentException – if input unsupported permission.
+         */
+        // Merged map available from getRequiredPermissionsForSchemaTypeVisibility
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @RequiresFeature(
+                enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+                name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+        @NonNull
+        public Builder addRequiredPermissionsForDocumentClassVisibility(
+                @NonNull Class<?> documentClass,
+                @AppSearchSupportedPermission @NonNull Set<Integer> permissions)
+                throws AppSearchException {
+            Preconditions.checkNotNull(documentClass);
+            resetIfBuilt();
+            DocumentClassFactoryRegistry registry = DocumentClassFactoryRegistry.getInstance();
+            DocumentClassFactory<?> factory = registry.getOrCreateFactory(documentClass);
+            return addRequiredPermissionsForSchemaTypeVisibility(
+                    factory.getSchemaName(), permissions);
+        }
+
+        /**  Clears all required permissions combinations for the given schema type.  */
+        @RequiresFeature(
+                enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+                name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
+        @NonNull
+        public Builder clearRequiredPermissionsForDocumentClassVisibility(
+                @NonNull Class<?> documentClass)
+                throws AppSearchException {
+            Preconditions.checkNotNull(documentClass);
+            resetIfBuilt();
+            DocumentClassFactoryRegistry registry = DocumentClassFactoryRegistry.getInstance();
+            DocumentClassFactory<?> factory = registry.getOrCreateFactory(documentClass);
+            return clearRequiredPermissionsForSchemaTypeVisibility(factory.getSchemaName());
+        }
 // @exportToFramework:endStrip()
 
         /**
@@ -497,7 +755,7 @@
          *
          * <p>Setting a version number that is different from the version number currently stored
          * in AppSearch will result in AppSearch calling the {@link Migrator}s provided to
-         * {@link AppSearchSession#setSchema} to migrate the documents already in AppSearch from
+         * {@link AppSearchSession#setSchemaAsync} to migrate the documents already in AppSearch from
          * the previous version to the one set in this request. The version number can be
          * updated without any other changes to the set of schemas.
          *
@@ -513,7 +771,7 @@
          *
          * @throws IllegalArgumentException if the version is negative.
          *
-         * @see AppSearchSession#setSchema
+         * @see AppSearchSession#setSchemaAsync
          * @see Migrator
          * @see SetSchemaRequest.Builder#setMigrator
          */
@@ -539,6 +797,7 @@
             // Create a copy because we're going to remove from the set for verification purposes.
             Set<String> referencedSchemas = new ArraySet<>(mSchemasNotDisplayedBySystem);
             referencedSchemas.addAll(mSchemasVisibleToPackages.keySet());
+            referencedSchemas.addAll(mSchemasVisibleToPermissions.keySet());
 
             for (AppSearchSchema schema : mSchemas) {
                 referencedSchemas.remove(schema.getSchemaType());
@@ -558,6 +817,7 @@
                     mSchemas,
                     mSchemasNotDisplayedBySystem,
                     mSchemasVisibleToPackages,
+                    mSchemasVisibleToPermissions,
                     mMigrators,
                     mForceOverride,
                     mVersion);
@@ -573,6 +833,8 @@
                 }
                 mSchemasVisibleToPackages = schemasVisibleToPackages;
 
+                mSchemasVisibleToPermissions = deepCopy(mSchemasVisibleToPermissions);
+
                 mSchemas = new ArraySet<>(mSchemas);
                 mSchemasNotDisplayedBySystem = new ArraySet<>(mSchemasNotDisplayedBySystem);
                 mMigrators = new ArrayMap<>(mMigrators);
@@ -580,4 +842,17 @@
             }
         }
     }
+
+    static ArrayMap<String, Set<Set<Integer>>> deepCopy(@NonNull Map<String,
+            Set<Set<Integer>>> original) {
+        ArrayMap<String, Set<Set<Integer>>> copy = new ArrayMap<>(original.size());
+        for (Map.Entry<String, Set<Set<Integer>>> entry : original.entrySet()) {
+            Set<Set<Integer>> valueCopy = new ArraySet<>();
+            for (Set<Integer> innerValue : entry.getValue()) {
+                valueCopy.add(new ArraySet<>(innerValue));
+            }
+            copy.put(entry.getKey(), valueCopy);
+        }
+        return copy;
+    }
 }
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaResponse.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaResponse.java
index 88e6645..3f8ce5e 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaResponse.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaResponse.java
@@ -30,7 +30,7 @@
 import java.util.List;
 import java.util.Set;
 
-/** The response class of {@link AppSearchSession#setSchema} */
+/** The response class of {@link AppSearchSession#setSchemaAsync} */
 public class SetSchemaResponse {
 
     private static final String DELETED_TYPES_FIELD = "deletedTypes";
@@ -102,7 +102,7 @@
      *
      * <p>A "deleted" type is a schema type that was previously a part of the database schema but
      * was not present in the {@link SetSchemaRequest} object provided in the
-     * {@link AppSearchSession#setSchema) call.
+     * {@link AppSearchSession#setSchemaAsync} call.
      *
      * <p>Documents for a deleted type are removed from the database.
      */
@@ -117,7 +117,7 @@
 
     /**
      * Returns a {@link Set} of schema type that were migrated by the
-     * {@link AppSearchSession#setSchema} call.
+     * {@link AppSearchSession#setSchemaAsync} call.
      *
      * <p> A "migrated" type is a schema type that has triggered a {@link Migrator} instance to
      * migrate documents of the schema type to another schema type, or to another version of the
@@ -139,13 +139,13 @@
 
     /**
      * Returns a {@link Set} of schema type whose new definitions set in the
-     * {@link AppSearchSession#setSchema} call were incompatible with the pre-existing schema.
+     * {@link AppSearchSession#setSchemaAsync} call were incompatible with the pre-existing schema.
      *
      * <p>If a {@link Migrator} is provided for this type and the migration is success triggered.
      * The type will also appear in {@link #getMigratedTypes()}.
      *
      * @see SetSchemaRequest
-     * @see AppSearchSession#setSchema
+     * @see AppSearchSession#setSchemaAsync
      * @see SetSchemaRequest.Builder#setForceOverride
      */
     @NonNull
@@ -281,7 +281,7 @@
 
     /**
      * The class represents a post-migrated {@link GenericDocument} that failed to be saved by
-     * {@link AppSearchSession#setSchema}.
+     * {@link AppSearchSession#setSchemaAsync}.
      */
     public static class MigrationFailure {
         private static final String SCHEMA_TYPE_FIELD = "schemaType";
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityDocument.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityDocument.java
new file mode 100644
index 0000000..6f04dc5
--- /dev/null
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityDocument.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 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.
+ * 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.appsearch.app;
+
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.collection.ArraySet;
+import androidx.core.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Holds the visibility settings that apply to a schema type.
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class VisibilityDocument extends GenericDocument {
+    /**
+     * The Schema type for documents that hold AppSearch's metadata, e.g. visibility settings.
+     */
+    public static final String SCHEMA_TYPE = "VisibilityType";
+    /** Namespace of documents that contain visibility settings */
+    public static final String NAMESPACE = "";
+
+    /**
+     * Property that holds the list of platform-hidden schemas, as part of the visibility settings.
+     */
+    private static final String NOT_DISPLAYED_BY_SYSTEM_PROPERTY = "notPlatformSurfaceable";
+
+    /** Property that holds the package name that can access a schema. */
+    private static final String PACKAGE_NAME_PROPERTY = "packageName";
+
+    /** Property that holds the SHA 256 certificate of the app that can access a schema. */
+    private static final String SHA_256_CERT_PROPERTY = "sha256Cert";
+
+    /** Property that holds the required permissions to access the schema. */
+    private static final String PERMISSION_PROPERTY = "permission";
+
+    // The initial schema version, one VisibilityDocument contains all visibility information for
+    // whole package.
+    public static final int SCHEMA_VERSION_DOC_PER_PACKAGE = 0;
+
+    // One VisibilityDocument contains visibility information for a single schema.
+    public static final int SCHEMA_VERSION_DOC_PER_SCHEMA = 1;
+
+    // One VisibilityDocument contains visibility information for a single schema.
+    public static final int SCHEMA_VERSION_NESTED_PERMISSION_SCHEMA = 2;
+
+    public static final int SCHEMA_VERSION_LATEST = SCHEMA_VERSION_NESTED_PERMISSION_SCHEMA;
+
+    /**
+     * Schema for the VisibilityStore's documents.
+     *
+     * <p>NOTE: If you update this, also update {@link #SCHEMA_VERSION_LATEST}.
+     */
+    public static final AppSearchSchema
+            SCHEMA = new AppSearchSchema.Builder(SCHEMA_TYPE)
+            .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder(
+                    NOT_DISPLAYED_BY_SYSTEM_PROPERTY)
+                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                    .build())
+            .addProperty(new AppSearchSchema.StringPropertyConfig.Builder(PACKAGE_NAME_PROPERTY)
+                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                    .build())
+            .addProperty(new AppSearchSchema.BytesPropertyConfig.Builder(SHA_256_CERT_PROPERTY)
+                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                    .build())
+            .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(PERMISSION_PROPERTY,
+                    VisibilityPermissionDocument.SCHEMA_TYPE)
+                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                    .build())
+            .build();
+
+    public VisibilityDocument(@NonNull GenericDocument genericDocument) {
+        super(genericDocument);
+    }
+
+    public VisibilityDocument(@NonNull Bundle bundle) {
+        super(bundle);
+    }
+
+    /** Returns whether this schema is visible to the system. */
+    public boolean isNotDisplayedBySystem() {
+        return getPropertyBoolean(NOT_DISPLAYED_BY_SYSTEM_PROPERTY);
+    }
+
+    /**
+     * Returns a package name array which could access this schema. Use {@link #getSha256Certs()}
+     * to get package's sha 256 certs. The same index of package names array and sha256Certs array
+     * represents same package.
+     */
+    @NonNull
+    public String[] getPackageNames() {
+        return getPropertyStringArray(PACKAGE_NAME_PROPERTY);
+    }
+
+    /**
+     * Returns a package sha256Certs array which could access this schema. Use
+     * {@link #getPackageNames()} to get package's name. The same index of package names array
+     * and sha256Certs array represents same package.
+     */
+    @NonNull
+    public byte[][] getSha256Certs() {
+        return getPropertyBytesArray(SHA_256_CERT_PROPERTY);
+    }
+
+    /**
+     * Returns an array of Android Permissions that caller mush hold to access the schema
+     * this {@link VisibilityDocument} represents.
+     */
+    @Nullable
+    public Set<Set<Integer>> getVisibleToPermissions() {
+        GenericDocument[] permissionDocuments = getPropertyDocumentArray(PERMISSION_PROPERTY);
+        if (permissionDocuments == null) {
+            return Collections.emptySet();
+        }
+        Set<Set<Integer>> visibleToPermissions = new ArraySet<>(permissionDocuments.length);
+        for (GenericDocument permissionDocument : permissionDocuments) {
+            visibleToPermissions.add(
+                    new VisibilityPermissionDocument(permissionDocument)
+                            .getAllRequiredPermissions());
+        }
+        return visibleToPermissions;
+    }
+
+    /** Builder for {@link VisibilityDocument}. */
+    public static class Builder extends GenericDocument.Builder<Builder> {
+        private final Set<PackageIdentifier> mPackageIdentifiers = new ArraySet<>();
+
+        /**
+         * Creates a {@link Builder} for a {@link VisibilityDocument}.
+         *
+         * @param id The SchemaType of the {@link AppSearchSchema} that this
+         *           {@link VisibilityDocument} represents. The package and database prefix will be
+         *           added in server side. We are using prefixed schema type to be the final id of
+         *           this {@link VisibilityDocument}.
+         */
+        public Builder(@NonNull String id) {
+            super(NAMESPACE, id, SCHEMA_TYPE);
+        }
+
+        /** Sets whether this schema has opted out of platform surfacing. */
+        @NonNull
+        public Builder setNotDisplayedBySystem(boolean notDisplayedBySystem) {
+            return setPropertyBoolean(NOT_DISPLAYED_BY_SYSTEM_PROPERTY,
+                    notDisplayedBySystem);
+        }
+
+        /** Add {@link PackageIdentifier} of packages which has access to this schema. */
+        @NonNull
+        public Builder addVisibleToPackages(@NonNull Set<PackageIdentifier> packageIdentifiers) {
+            Preconditions.checkNotNull(packageIdentifiers);
+            mPackageIdentifiers.addAll(packageIdentifiers);
+            return this;
+        }
+
+        /** Add {@link PackageIdentifier} of packages which has access to this schema. */
+        @NonNull
+        public Builder addVisibleToPackage(@NonNull PackageIdentifier packageIdentifier) {
+            Preconditions.checkNotNull(packageIdentifier);
+            mPackageIdentifiers.add(packageIdentifier);
+            return this;
+        }
+
+        /**
+         * Set required permission sets for a package needs to hold to the schema this
+         * {@link VisibilityDocument} represents.
+         *
+         * <p> The querier could have access if they holds ALL required permissions of ANY of the
+         * individual value sets.
+         */
+        @NonNull
+        public Builder setVisibleToPermissions(@NonNull Set<Set<Integer>> visibleToPermissions) {
+            Preconditions.checkNotNull(visibleToPermissions);
+            VisibilityPermissionDocument[] permissionDocuments =
+                    new VisibilityPermissionDocument[visibleToPermissions.size()];
+            int i = 0;
+            for (Set<Integer> allRequiredPermissions : visibleToPermissions) {
+                permissionDocuments[i++] = new VisibilityPermissionDocument
+                        .Builder(NAMESPACE, /*id=*/String.valueOf(i))
+                        .setVisibleToAllRequiredPermissions(allRequiredPermissions)
+                        .build();
+            }
+            setPropertyDocument(PERMISSION_PROPERTY, permissionDocuments);
+            return this;
+        }
+
+        /** Build a {@link VisibilityDocument} */
+        @Override
+        @NonNull
+        public VisibilityDocument build() {
+            String[] packageNames = new String[mPackageIdentifiers.size()];
+            byte[][] sha256Certs = new byte[mPackageIdentifiers.size()][32];
+            int i = 0;
+            for (PackageIdentifier packageIdentifier : mPackageIdentifiers) {
+                packageNames[i] = packageIdentifier.getPackageName();
+                sha256Certs[i] = packageIdentifier.getSha256Certificate();
+                ++i;
+            }
+            setPropertyString(PACKAGE_NAME_PROPERTY, packageNames);
+            setPropertyBytes(SHA_256_CERT_PROPERTY, sha256Certs);
+            return new VisibilityDocument(super.build());
+        }
+    }
+
+
+    /**  Build the List of {@link VisibilityDocument} from visibility settings. */
+    @NonNull
+    public static List<VisibilityDocument> toVisibilityDocuments(
+            @NonNull SetSchemaRequest setSchemaRequest) {
+        Set<AppSearchSchema> searchSchemas = setSchemaRequest.getSchemas();
+        Set<String> schemasNotDisplayedBySystem = setSchemaRequest.getSchemasNotDisplayedBySystem();
+        Map<String, Set<PackageIdentifier>> schemasVisibleToPackages =
+                setSchemaRequest.getSchemasVisibleToPackages();
+        Map<String, Set<Set<Integer>>> schemasVisibleToPermissions =
+                setSchemaRequest.getRequiredPermissionsForSchemaTypeVisibility();
+
+        List<VisibilityDocument> visibilityDocuments = new ArrayList<>(searchSchemas.size());
+
+        for (AppSearchSchema searchSchema : searchSchemas) {
+            String schemaType = searchSchema.getSchemaType();
+            VisibilityDocument.Builder documentBuilder =
+                    new VisibilityDocument.Builder(/*id=*/searchSchema.getSchemaType());
+            documentBuilder.setNotDisplayedBySystem(
+                    schemasNotDisplayedBySystem.contains(schemaType));
+
+            if (schemasVisibleToPackages.containsKey(schemaType)) {
+                documentBuilder.addVisibleToPackages(schemasVisibleToPackages.get(schemaType));
+            }
+
+            if (schemasVisibleToPermissions.containsKey(schemaType)) {
+                documentBuilder.setVisibleToPermissions(
+                        schemasVisibleToPermissions.get(schemaType));
+            }
+            visibilityDocuments.add(documentBuilder.build());
+        }
+        return visibilityDocuments;
+    }
+}
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityPermissionDocument.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityPermissionDocument.java
new file mode 100644
index 0000000..e859cb9
--- /dev/null
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityPermissionDocument.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2022 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.appsearch.app;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.collection.ArraySet;
+
+import java.util.Set;
+
+/**
+ * The nested document that holds all required permissions for a caller need to hold to access the
+ * schema which the outer {@link VisibilityDocument} represents.
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class VisibilityPermissionDocument extends GenericDocument {
+
+    /**
+     * The Schema type for documents that hold AppSearch's metadata, e.g. visibility settings.
+     */
+    public static final String SCHEMA_TYPE = "VisibilityPermissionType";
+
+    /** Property that holds the required permissions to access the schema. */
+    private static final String ALL_REQUIRED_PERMISSIONS_PROPERTY = "allRequiredPermissions";
+
+    /**
+     * Schema for the VisibilityStore's documents.
+     *
+     * <p>NOTE: If you update this, also update {@link VisibilityDocument#SCHEMA_VERSION_LATEST}.
+     */
+    public static final AppSearchSchema
+            SCHEMA = new AppSearchSchema.Builder(SCHEMA_TYPE)
+            .addProperty(new AppSearchSchema.LongPropertyConfig
+                    .Builder(ALL_REQUIRED_PERMISSIONS_PROPERTY)
+                    .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+                    .build())
+            .build();
+
+    VisibilityPermissionDocument(@NonNull GenericDocument genericDocument) {
+        super(genericDocument);
+    }
+
+    /**
+     * Returns an array of Android Permissions that caller mush hold to access the schema
+     * that the outer {@link VisibilityDocument} represents.
+     */
+    @Nullable
+    public Set<Integer> getAllRequiredPermissions() {
+        return toInts(getPropertyLongArray(ALL_REQUIRED_PERMISSIONS_PROPERTY));
+    }
+
+    /** Builder for {@link VisibilityPermissionDocument}. */
+    public static class Builder extends GenericDocument.Builder<Builder> {
+
+        /**
+         * Creates a {@link VisibilityDocument.Builder} for a {@link VisibilityDocument}.
+         */
+        public Builder(@NonNull String namespace, @NonNull String id) {
+            super(namespace, id, SCHEMA_TYPE);
+        }
+
+        /** Sets whether this schema has opted out of platform surfacing. */
+        @NonNull
+        public Builder setVisibleToAllRequiredPermissions(
+                @NonNull Set<Integer> allRequiredPermissions) {
+            setPropertyLong(ALL_REQUIRED_PERMISSIONS_PROPERTY, toLongs(allRequiredPermissions));
+            return this;
+        }
+
+        /** Build a {@link VisibilityPermissionDocument} */
+        @Override
+        @NonNull
+        public VisibilityPermissionDocument build() {
+            return new VisibilityPermissionDocument(super.build());
+        }
+    }
+
+    @NonNull
+    static long[] toLongs(@NonNull Set<Integer> properties) {
+        long[] outputs = new long[properties.size()];
+        int i = 0;
+        for (int property : properties) {
+            outputs[i++] = property;
+        }
+        return outputs;
+    }
+
+    @Nullable
+    private static Set<Integer> toInts(@Nullable long[] properties) {
+        if (properties == null) {
+            return null;
+        }
+        Set<Integer> outputs = new ArraySet<>(properties.length);
+        for (long property : properties) {
+            outputs.add((int) property);
+        }
+        return outputs;
+    }
+}
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/AppSearchObserverCallback.java b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/AppSearchObserverCallback.java
index c040aa2..c01917e 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/AppSearchObserverCallback.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/AppSearchObserverCallback.java
@@ -16,23 +16,13 @@
 
 package androidx.appsearch.observer;
 
-import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
 
 /**
- * An interface which apps can implement to subscribe to notifications of changes to AppSearch data.
+ * @deprecated use {@link ObserverCallback} instead.
+ * @hide
  */
-public interface AppSearchObserverCallback {
-    /**
-     * Callback to trigger after schema changes (schema type added, updated or removed).
-     *
-     * @param changeInfo Information about the nature of the change.
-     */
-    void onSchemaChanged(@NonNull SchemaChangeInfo changeInfo);
-
-    /**
-     * Callback to trigger after document changes (documents added, updated or removed).
-     *
-     * @param changeInfo Information about the nature of the change.
-     */
-    void onDocumentChanged(@NonNull DocumentChangeInfo changeInfo);
-}
+// TODO(b/209734214): Remove this after dogfooders and devices have migrated away from this class.
+@Deprecated
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public interface AppSearchObserverCallback extends ObserverCallback {}
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/DocumentChangeInfo.java b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/DocumentChangeInfo.java
index 0fd9ae2..32d19ad 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/DocumentChangeInfo.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/DocumentChangeInfo.java
@@ -21,8 +21,11 @@
 import androidx.core.util.ObjectsCompat;
 import androidx.core.util.Preconditions;
 
+import java.util.Collections;
+import java.util.Set;
+
 /**
- * Contains information about an individual change detected by an {@link AppSearchObserverCallback}.
+ * Contains information about an individual change detected by an {@link ObserverCallback}.
  *
  * <p>This class reports information about document changes, i.e. when documents were added, updated
  * or removed.
@@ -30,8 +33,11 @@
  * <p>Changes are grouped by package, database, schema type and namespace. Each unique
  * combination of these items will generate a unique {@link DocumentChangeInfo}.
  *
+ * <p>Notifications are only sent for documents whose schema type matches an observer's schema
+ * filters (as determined by {@link ObserverSpec#getFilterSchemas}).
+ *
  * <p>Note that document changes that happen during schema migration from calling
- * {@link androidx.appsearch.app.AppSearchSession#setSchema} are not reported via this class.
+ * {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync} are not reported via this class.
  * Such changes are reported through {@link SchemaChangeInfo}.
  */
 public final class DocumentChangeInfo {
@@ -39,8 +45,7 @@
     private final String mDatabase;
     private final String mNamespace;
     private final String mSchemaName;
-
-    // TODO(b/193494000): Add the set of changed document IDs to this class
+    private final Set<String> mChangedDocumentIds;
 
     /**
      * Constructs a new {@link DocumentChangeInfo}.
@@ -49,16 +54,21 @@
      * @param database The database in which the documents that changed reside.
      * @param namespace    The namespace in which the documents that changed reside.
      * @param schemaName   The name of the schema type that contains the changed documents.
+     * @param changedDocumentIds The set of document IDs that have been changed as part of this
+     *                   notification.
      */
     public DocumentChangeInfo(
             @NonNull String packageName,
             @NonNull String database,
             @NonNull String namespace,
-            @NonNull String schemaName) {
+            @NonNull String schemaName,
+            @NonNull Set<String> changedDocumentIds) {
         mPackageName = Preconditions.checkNotNull(packageName);
         mDatabase = Preconditions.checkNotNull(database);
         mNamespace = Preconditions.checkNotNull(namespace);
         mSchemaName = Preconditions.checkNotNull(schemaName);
+        mChangedDocumentIds = Collections.unmodifiableSet(
+                Preconditions.checkNotNull(changedDocumentIds));
     }
 
     /** Returns the package name of the app which owns the documents that changed. */
@@ -85,6 +95,16 @@
         return mSchemaName;
     }
 
+    /**
+     * Returns the set of document IDs that have been changed as part of this notification.
+     *
+     * <p>This will never be empty.
+     */
+    @NonNull
+    public Set<String> getChangedDocumentIds() {
+        return mChangedDocumentIds;
+    }
+
     @Override
     public boolean equals(@Nullable Object o) {
         if (this == o) return true;
@@ -93,12 +113,14 @@
         return mPackageName.equals(that.mPackageName)
                 && mDatabase.equals(that.mDatabase)
                 && mNamespace.equals(that.mNamespace)
-                && mSchemaName.equals(that.mSchemaName);
+                && mSchemaName.equals(that.mSchemaName)
+                && mChangedDocumentIds.equals(that.mChangedDocumentIds);
     }
 
     @Override
     public int hashCode() {
-        return ObjectsCompat.hash(mPackageName, mDatabase, mNamespace, mSchemaName);
+        return ObjectsCompat.hash(
+                mPackageName, mDatabase, mNamespace, mSchemaName, mChangedDocumentIds);
     }
 
     @NonNull
@@ -109,6 +131,7 @@
                 + ", database='" + mDatabase + '\''
                 + ", namespace='" + mNamespace + '\''
                 + ", schemaName='" + mSchemaName + '\''
+                + ", changedDocumentIds='" + mChangedDocumentIds + '\''
                 + '}';
     }
 }
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/ObserverCallback.java b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/ObserverCallback.java
new file mode 100644
index 0000000..cae945a
--- /dev/null
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/ObserverCallback.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ * 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.appsearch.observer;
+
+import androidx.annotation.NonNull;
+
+/**
+ * An interface which apps can implement to subscribe to notifications of changes to AppSearch data.
+ */
+public interface ObserverCallback {
+    /**
+     * Callback to trigger after schema changes (schema type added, updated or removed).
+     *
+     * @param changeInfo Information about the nature of the change.
+     */
+    void onSchemaChanged(@NonNull SchemaChangeInfo changeInfo);
+
+    /**
+     * Callback to trigger after document changes (documents added, updated or removed).
+     *
+     * @param changeInfo Information about the nature of the change.
+     */
+    void onDocumentChanged(@NonNull DocumentChangeInfo changeInfo);
+}
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/ObserverSpec.java b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/ObserverSpec.java
index e8979e5..6e3705e 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/ObserverSpec.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/ObserverSpec.java
@@ -37,8 +37,8 @@
 import java.util.Set;
 
 /**
- * Configures the types, namespaces and other properties that {@link AppSearchObserverCallback}
- * instances match against.
+ * Configures the types, namespaces and other properties that {@link ObserverCallback} instances
+ * match against.
  */
 public final class ObserverSpec {
     private static final String FILTER_SCHEMA_FIELD = "filterSchema";
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/SchemaChangeInfo.java b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/SchemaChangeInfo.java
index 6eff8c4..e912cf8 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/SchemaChangeInfo.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/SchemaChangeInfo.java
@@ -21,11 +21,15 @@
 import androidx.core.util.ObjectsCompat;
 import androidx.core.util.Preconditions;
 
+import java.util.Collections;
+import java.util.Set;
+
 /**
- * Contains information about a schema change detected by an {@link AppSearchObserverCallback}.
+ * Contains information about a schema change detected by an {@link ObserverCallback}.
  *
  * <p>This object will be sent when a schema type having a name matching an observer's schema
- * type filters has been added, updated, or removed.
+ * filters (as determined by {@link ObserverSpec#getFilterSchemas}) has been added, updated, or
+ * removed.
  *
  * <p>Note that schema changes may cause documents to be migrated or removed. When this happens,
  * individual document updates will NOT be dispatched via {@link DocumentChangeInfo}. The only
@@ -35,18 +39,23 @@
 public final class SchemaChangeInfo {
     private final String mPackageName;
     private final String mDatabaseName;
-
-    // TODO(b/193494000): Add the set of changed schema names to this class
+    private final Set<String> mChangedSchemaNames;
 
     /**
      * Constructs a new {@link SchemaChangeInfo}.
      *
      * @param packageName     The package name of the app which owns the schema that changed.
      * @param databaseName    The database in which the schema that changed resides.
+     * @param changedSchemaNames Names of schemas that have changed as part of this notification.
      */
-    public SchemaChangeInfo(@NonNull String packageName, @NonNull String databaseName) {
+    public SchemaChangeInfo(
+            @NonNull String packageName,
+            @NonNull String databaseName,
+            @NonNull Set<String> changedSchemaNames) {
         mPackageName = Preconditions.checkNotNull(packageName);
         mDatabaseName = Preconditions.checkNotNull(databaseName);
+        mChangedSchemaNames = Collections.unmodifiableSet(
+                Preconditions.checkNotNull(changedSchemaNames));
     }
 
     /** Returns the package name of the app which owns the schema that changed. */
@@ -61,17 +70,29 @@
         return mDatabaseName;
     }
 
+    /**
+     * Returns the names of schema types affected by this change notification.
+     *
+     * <p>This will never be empty.
+     */
+    @NonNull
+    public Set<String> getChangedSchemaNames() {
+        return mChangedSchemaNames;
+    }
+
     @Override
     public boolean equals(@Nullable Object o) {
         if (this == o) return true;
         if (!(o instanceof SchemaChangeInfo)) return false;
         SchemaChangeInfo that = (SchemaChangeInfo) o;
-        return mPackageName.equals(that.mPackageName) && mDatabaseName.equals(that.mDatabaseName);
+        return mPackageName.equals(that.mPackageName)
+                && mDatabaseName.equals(that.mDatabaseName)
+                && mChangedSchemaNames.equals(that.mChangedSchemaNames);
     }
 
     @Override
     public int hashCode() {
-        return ObjectsCompat.hash(mPackageName, mDatabaseName);
+        return ObjectsCompat.hash(mPackageName, mDatabaseName, mChangedSchemaNames);
     }
 
     @NonNull
@@ -80,6 +101,7 @@
         return "SchemaChangeInfo{"
                 + "packageName='" + mPackageName + '\''
                 + ", databaseName='" + mDatabaseName + '\''
+                + ", changedSchemaNames='" + mChangedSchemaNames + '\''
                 + '}';
     }
 }
diff --git a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/AppSearchCompiler.java b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/AppSearchCompiler.java
index 90f31aa..b59bea9 100644
--- a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/AppSearchCompiler.java
+++ b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/AppSearchCompiler.java
@@ -89,20 +89,22 @@
             Set<TypeElement> documentElements =
                     typesIn(elementsByAnnotation.get(
                             IntrospectionHelper.DOCUMENT_ANNOTATION_CLASS));
+
+            ImmutableSet.Builder<Element> nextRound = new ImmutableSet.Builder<>();
             for (TypeElement document : documentElements) {
                 try {
                     processDocument(document);
                 } catch (MissingTypeException e) {
                     // Save it for next round to wait for the AutoValue annotation processor to
                     // be run first.
-                    return ImmutableSet.of(e.getTypeName());
+                    nextRound.add(document);
                 } catch (ProcessingException e) {
                     // Prints error message.
                     e.printDiagnostic(mMessager);
                 }
             }
-            // No elements will be passed to next round of processing.
-            return ImmutableSet.of();
+            // Pass elements to next round of processing.
+            return nextRound.build();
         }
 
         private void processDocument(@NonNull TypeElement element)
diff --git a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/CodeGenerator.java b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/CodeGenerator.java
index f74e2bb..2339f36 100644
--- a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/CodeGenerator.java
+++ b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/CodeGenerator.java
@@ -82,7 +82,7 @@
      */
     private TypeSpec createClass() throws ProcessingException {
         // Gets the full name of target class.
-        String qualifiedName = mModel.getClassElement().getQualifiedName().toString();
+        String qualifiedName = mModel.getQualifiedDocumentClassName();
         String className = qualifiedName.substring(mOutputPackage.length() + 1);
         ClassName genClassName = mHelper.getDocumentClassFactoryForClass(mOutputPackage, className);
 
diff --git a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentModel.java b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentModel.java
index 9603065..a8bdcdb 100644
--- a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentModel.java
+++ b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentModel.java
@@ -65,6 +65,8 @@
     private final IntrospectionHelper mHelper;
     private final TypeElement mClass;
     private final AnnotationMirror mDocumentAnnotation;
+    // The name of the original class annotated with @Document
+    private final String mQualifiedDocumentClassName;
     // Warning: if you change this to a HashSet, we may choose different getters or setters from
     // run to run, causing the generated code to bounce.
     private final Set<ExecutableElement> mAllMethods = new LinkedHashSet<>();
@@ -116,6 +118,7 @@
             mAllMethods.addAll(
                     ElementFilter.methodsIn(generatedAutoValueElement.getEnclosedElements()));
 
+            mQualifiedDocumentClassName = generatedAutoValueElement.getQualifiedName().toString();
             scanFields(generatedAutoValueElement);
             scanCreationMethods(creationMethods);
         } else {
@@ -135,6 +138,7 @@
                 }
             }
 
+            mQualifiedDocumentClassName = clazz.getQualifiedName().toString();
             scanFields(mClass);
             scanCreationMethods(creationMethods);
         }
@@ -169,6 +173,15 @@
         return mClass;
     }
 
+    /**
+     * The name of the original class annotated with @Document
+     * @return the class name
+     */
+    @NonNull
+    public String getQualifiedDocumentClassName() {
+        return mQualifiedDocumentClassName;
+    }
+
     @NonNull
     public String getSchemaName() {
         Map<String, Object> params =
diff --git a/appsearch/compiler/src/test/java/androidx/appsearch/compiler/AppSearchCompilerTest.java b/appsearch/compiler/src/test/java/androidx/appsearch/compiler/AppSearchCompilerTest.java
index 45a6f8f..4d0122a 100644
--- a/appsearch/compiler/src/test/java/androidx/appsearch/compiler/AppSearchCompilerTest.java
+++ b/appsearch/compiler/src/test/java/androidx/appsearch/compiler/AppSearchCompilerTest.java
@@ -917,6 +917,45 @@
     }
 
     @Test
+    public void testMultipleNestedAutoValueDocument() throws IOException {
+        Compilation compilation = compile(
+                "import com.google.auto.value.AutoValue;\n"
+                        + "import com.google.auto.value.AutoValue.*;\n"
+                        + "@Document\n"
+                        + "@AutoValue\n"
+                        + "public abstract class Gift {\n"
+                        + "  @CopyAnnotations @Document.Id abstract String id();\n"
+                        + "  @CopyAnnotations @Document.Namespace abstract String namespace();\n"
+                        + "  @CopyAnnotations\n"
+                        + "  @Document.StringProperty abstract String property();\n"
+                        + "  public static Gift create(String id, String namespace, String"
+                        + " property) {\n"
+                        + "    return new AutoValue_Gift(id, namespace, property);\n"
+                        + "  }\n"
+                        + "  @Document\n"
+                        + "  @AutoValue\n"
+                        + "  abstract static class B {\n"
+                        + "    @CopyAnnotations @Document.Id abstract String id();\n"
+                        + "    @CopyAnnotations @Document.Namespace abstract String namespace();\n"
+                        + "    public static B create(String id, String namespace) {\n"
+                        + "      return new AutoValue_Gift_B(id, namespace);\n"
+                        + "    }\n"
+                        + "  }\n"
+                        + "  @Document\n"
+                        + "  @AutoValue\n"
+                        + "  abstract static class A {\n"
+                        + "    @CopyAnnotations @Document.Id abstract String id();\n"
+                        + "    @CopyAnnotations @Document.Namespace abstract String namespace();\n"
+                        + "    public static A create(String id, String namespace) {\n"
+                        + "      return new AutoValue_Gift_A(id, namespace);\n"
+                        + "    }\n"
+                        + "  }\n"
+                        + "}\n");
+        assertThat(compilation).succeededWithoutWarnings();
+        checkEqualsGolden("AutoValue_Gift_A.java");
+    }
+
+    @Test
     public void testAutoValueDocument() throws IOException {
         Compilation compilation = compile(
                 "import com.google.auto.value.AutoValue;\n"
@@ -935,7 +974,7 @@
                         + "}\n");
 
         assertThat(compilation).succeededWithoutWarnings();
-        checkEqualsGolden("Gift.java");
+        checkEqualsGolden("AutoValue_Gift.java");
     }
 
     @Test
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAutoValueDocument.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAutoValueDocument.JAVA
index 47e6df5..09eecaf 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAutoValueDocument.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAutoValueDocument.JAVA
@@ -9,7 +9,7 @@
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
-public class $$__AppSearch__Gift implements DocumentClassFactory<Gift> {
+public class $$__AppSearch__AutoValue_Gift implements DocumentClassFactory<Gift> {
   public static final String SCHEMA_NAME = "Gift";
 
   @Override
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testMultipleNestedAutoValueDocument.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testMultipleNestedAutoValueDocument.JAVA
new file mode 100644
index 0000000..dd3c696
--- /dev/null
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testMultipleNestedAutoValueDocument.JAVA
@@ -0,0 +1,40 @@
+package com.example.appsearch;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.DocumentClassFactory;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Override;
+import java.lang.String;
+import javax.annotation.processing.Generated;
+
+@Generated("androidx.appsearch.compiler.AppSearchCompiler")
+public class $$__AppSearch__AutoValue_Gift_A implements DocumentClassFactory<Gift.A> {
+  public static final String SCHEMA_NAME = "A";
+
+  @Override
+  public String getSchemaName() {
+    return SCHEMA_NAME;
+  }
+
+  @Override
+  public AppSearchSchema getSchema() throws AppSearchException {
+    return new AppSearchSchema.Builder(SCHEMA_NAME)
+          .build();
+  }
+
+  @Override
+  public GenericDocument toGenericDocument(Gift.A document) throws AppSearchException {
+    GenericDocument.Builder<?> builder =
+        new GenericDocument.Builder<>(document.namespace(), document.id(), SCHEMA_NAME);
+    return builder.build();
+  }
+
+  @Override
+  public Gift.A fromGenericDocument(GenericDocument genericDoc) throws AppSearchException {
+    String idConv = genericDoc.getId();
+    String namespaceConv = genericDoc.getNamespace();
+    Gift.A document = Gift.A.create(idConv, namespaceConv);
+    return document;
+  }
+}
diff --git a/appsearch/exportToFramework.py b/appsearch/exportToFramework.py
index e3d4c59..48ec64b 100755
--- a/appsearch/exportToFramework.py
+++ b/appsearch/exportToFramework.py
@@ -71,7 +71,7 @@
         '../../../prebuilts/tools/common/google-java-format/google-java-format')
 
 # Miscellaneous constants
-CHANGEID_FILE_NAME = 'synced_jetpack_changeid.txt'
+SHA_FILE_NAME = 'synced_jetpack_sha.txt'
 
 
 class ExportToFramework:
@@ -96,6 +96,10 @@
             print('Skipping: "%s" -> "%s"' % (source_path, dest_path), file=sys.stderr)
             return
 
+        copyToPath = re.search(r'@exportToFramework:copyToPath\(([^)]+)\)', contents)
+        if copyToPath:
+          dest_path = os.path.join(self._framework_appsearch_root, copyToPath.group(1))
+
         print('Copy: "%s" -> "%s"' % (source_path, dest_path), file=sys.stderr)
         if transform_func:
             contents = transform_func(contents)
@@ -133,7 +137,7 @@
                     flags=re.MULTILINE)
 
         # Apply in-place replacements
-        return (contents
+        contents = (contents
             .replace('androidx.appsearch.app', 'android.app.appsearch')
             .replace(
                     'androidx.appsearch.localstorage.',
@@ -161,11 +165,20 @@
             .replace('@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)', '')
             .replace('Preconditions.checkNotNull(', 'Objects.requireNonNull(')
             .replace('ObjectsCompat.', 'Objects.')
+
             .replace('/*@exportToFramework:CurrentTimeMillisLong*/', '@CurrentTimeMillisLong')
             .replace('/*@exportToFramework:UnsupportedAppUsage*/', '@UnsupportedAppUsage')
             .replace('<!--@exportToFramework:hide-->', '@hide')
             .replace('// @exportToFramework:skipFile()', '')
         )
+        contents = re.sub(r'\/\/ @exportToFramework:copyToPath\([^)]+\)', '', contents)
+
+        # Jetpack methods have the Async suffix, but framework doesn't. Strip the Async suffix
+        # to allow the same documentation to compile for both.
+        contents = re.sub(r'(#[a-zA-Z0-9_]+)Async}', r'\1}', contents)
+        contents = re.sub(
+                r'(\@see [^#]+#[a-zA-Z0-9_]+)Async$', r'\1', contents, flags=re.MULTILINE)
+        return contents
 
     def _TransformTestCode(self, contents):
         contents = (contents
@@ -318,19 +331,26 @@
         self._ExportImplCode()
         self._FormatWrittenFiles()
 
-    def WriteChangeIdFile(self, changeid):
-        """Copies the changeid of the most recent public CL into a file on the framework side.
+    def WriteShaFile(self, sha):
+        """Copies the git sha of the most recent public CL into a file on the framework side.
 
         This file is used for tracking, to determine what framework is synced to.
 
-        You must always provide a changeid of an exported, preferably even submitted CL. If you
-        abandon the CL pointed to by this changeid, the next person syncing framework will be unable
-        to find what CL it is synced to.
+        You must always provide a sha of a submitted submitted git commit. If you abandon the CL
+        pointed to by this sha, the next person syncing framework will be unable to find what CL it
+        is synced to.
+
+        The previous content of the sha file, if any, is returned.
         """
-        file_path = os.path.join(self._framework_appsearch_root, CHANGEID_FILE_NAME)
+        file_path = os.path.join(self._framework_appsearch_root, SHA_FILE_NAME)
+        old_sha = None
+        if os.path.isfile(file_path):
+          with open(file_path, 'r') as fh:
+              old_sha = fh.read().rstrip()
         with open(file_path, 'w') as fh:
-            print(changeid, file=fh)
+            print(sha, file=fh)
         print('Wrote "%s"' % file_path)
+        return old_sha
 
 
 if __name__ == '__main__':
@@ -339,6 +359,12 @@
                   sys.argv[0]),
               file=sys.stderr)
         sys.exit(1)
+    if sys.argv[2].startswith('I'):
+        print('Error: Git sha "%s" looks like a changeid. Please provide a git sha instead.' % (
+                  sys.argv[2]),
+              file=sys.stderr)
+        sys.exit(1)
+
     source_dir = os.path.normpath(os.path.dirname(sys.argv[0]))
     dest_dir = os.path.normpath(sys.argv[1])
     dest_dir = os.path.join(dest_dir, 'packages/modules/AppSearch')
@@ -349,4 +375,10 @@
         sys.exit(1)
     exporter = ExportToFramework(source_dir, dest_dir)
     exporter.ExportCode()
-    exporter.WriteChangeIdFile(sys.argv[2])
+
+    # Update the sha file
+    new_sha = sys.argv[2]
+    old_sha = exporter.WriteShaFile(new_sha)
+    if old_sha and old_sha != new_sha:
+      print('Command to diff old version to new version:')
+      print('  git log %s..%s -- appsearch/' % (old_sha, new_sha))
diff --git a/browser/browser/src/main/java/androidx/browser/browseractions/BrowserActionsIntent.java b/browser/browser/src/main/java/androidx/browser/browseractions/BrowserActionsIntent.java
index 862a9ff..88036ff 100644
--- a/browser/browser/src/main/java/androidx/browser/browseractions/BrowserActionsIntent.java
+++ b/browser/browser/src/main/java/androidx/browser/browseractions/BrowserActionsIntent.java
@@ -381,6 +381,7 @@
      * @hide
      */
     @RestrictTo(LIBRARY)
+    @SuppressWarnings("deprecation")
     @NonNull
     public static List<ResolveInfo> getBrowserActionsIntentHandlers(@NonNull Context context) {
         Intent intent =
@@ -389,7 +390,7 @@
         return pm.queryIntentActivities(intent, PackageManager.MATCH_ALL);
     }
 
-    @SuppressWarnings("NullAway") // TODO: b/141869398
+    @SuppressWarnings({"NullAway", "deprecation"}) // TODO: b/141869398
     private static void openFallbackBrowserActionsMenu(Context context, Intent intent) {
         Uri uri = intent.getData();
         ArrayList<Bundle> bundles = intent.getParcelableArrayListExtra(EXTRA_MENU_ITEMS);
diff --git a/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsSessionToken.java b/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsSessionToken.java
index 40386b6..f1675f2 100644
--- a/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsSessionToken.java
+++ b/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsSessionToken.java
@@ -86,6 +86,7 @@
      *               {@link CustomTabsIntent#EXTRA_SESSION}.
      * @return The token that was generated.
      */
+    @SuppressWarnings("deprecation")
     public static @Nullable CustomTabsSessionToken getSessionTokenFromIntent(
             @NonNull Intent intent) {
         Bundle b = intent.getExtras();
diff --git a/browser/browser/src/main/java/androidx/browser/customtabs/TrustedWebUtils.java b/browser/browser/src/main/java/androidx/browser/customtabs/TrustedWebUtils.java
index b95bd78..37d604e 100644
--- a/browser/browser/src/main/java/androidx/browser/customtabs/TrustedWebUtils.java
+++ b/browser/browser/src/main/java/androidx/browser/customtabs/TrustedWebUtils.java
@@ -119,6 +119,7 @@
      * @return Whether the specified Custom Tabs provider supports the specified splash screen
      *         feature/version.
      */
+    @SuppressWarnings("deprecation")
     public static boolean areSplashScreensSupported(@NonNull Context context,
             @NonNull String packageName, @NonNull String version) {
         Intent serviceIntent = new Intent()
diff --git a/browser/browser/src/test/java/androidx/browser/customtabs/CustomTabsIntentTest.java b/browser/browser/src/test/java/androidx/browser/customtabs/CustomTabsIntentTest.java
index f3fd01e..4a5ac59 100644
--- a/browser/browser/src/test/java/androidx/browser/customtabs/CustomTabsIntentTest.java
+++ b/browser/browser/src/test/java/androidx/browser/customtabs/CustomTabsIntentTest.java
@@ -274,6 +274,7 @@
         assertNullSessionInExtras(intent);
     }
 
+    @SuppressWarnings("deprecation")
     @Test
     public void putsSessionBinderAndId_IfSuppliedInConstructor() {
         CustomTabsSession session = TestUtil.makeMockSession();
@@ -283,6 +284,7 @@
         assertEquals(session.getId(), intent.getParcelableExtra(CustomTabsIntent.EXTRA_SESSION_ID));
     }
 
+    @SuppressWarnings("deprecation")
     @Test
     public void putsSessionBinderAndId_IfSuppliedInSetter() {
         CustomTabsSession session = TestUtil.makeMockSession();
@@ -292,6 +294,7 @@
         assertEquals(session.getId(), intent.getParcelableExtra(CustomTabsIntent.EXTRA_SESSION_ID));
     }
 
+    @SuppressWarnings("deprecation")
     @Test
     public void putsPendingSessionId() {
         CustomTabsSession.PendingSession pendingSession = TestUtil.makeMockPendingSession();
diff --git a/browser/browser/src/test/java/androidx/browser/customtabs/TestUtil.java b/browser/browser/src/test/java/androidx/browser/customtabs/TestUtil.java
index 318a99a..fa0c171 100644
--- a/browser/browser/src/test/java/androidx/browser/customtabs/TestUtil.java
+++ b/browser/browser/src/test/java/androidx/browser/customtabs/TestUtil.java
@@ -55,6 +55,7 @@
         return PendingIntent.getBroadcast(mock(Context.class), 0, new Intent(), 0);
     }
 
+    @SuppressWarnings("deprecation")
     public static void assertIntentHasSession(@NonNull Intent intent,
             @NonNull CustomTabsSession session) {
         assertEquals(session.getBinder(), intent.getExtras().getBinder(
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/LintConfiguration.kt b/buildSrc/private/src/main/kotlin/androidx/build/LintConfiguration.kt
index bf0b082..25d8376 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/LintConfiguration.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/LintConfiguration.kt
@@ -223,6 +223,10 @@
         // Reenable after upgradingto 7.1.0-beta01
         disable.add("SupportAnnotationUsage")
 
+        // Broken when building with compileSdk 31, b/208451611
+        disable.add("VectorPath")
+        disable.add("InvalidVectorPath")
+
         // Provide stricter enforcement for project types intended to run on a device.
         if (extension.type.compilationTarget == CompilationTarget.DEVICE) {
             fatal.add("Assert")
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/SupportConfig.kt b/buildSrc/public/src/main/kotlin/androidx/build/SupportConfig.kt
index b8ed461..11db7d1 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/SupportConfig.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/SupportConfig.kt
@@ -34,7 +34,7 @@
      * Either an integer value or a pre-release platform code, prefixed with "android-" (ex.
      * "android-28" or "android-Q") as you would see within the SDK's platforms directory.
      */
-    const val COMPILE_SDK_VERSION = "android-31"
+    const val COMPILE_SDK_VERSION = "android-Tiramisu"
 
     /**
      * The Android SDK version to use for targetSdkVersion meta-data.
diff --git a/busytown/impl/check_translations.sh b/busytown/impl/check_translations.sh
index f18ec2b..35501ad 100755
--- a/busytown/impl/check_translations.sh
+++ b/busytown/impl/check_translations.sh
@@ -19,12 +19,13 @@
 expect="$tempdir/expect.txt"
 find . \
     \( \
-      -iname '*samples*' \
+      -iname '*sample*' \
+      -o -iname '*donottranslate*' \
       -o -iname '*debug*' \
       -o -iname '*test*' \
     \) \
     -prune -o \
-    -path '*/res/values/strings.xml' \
+    -path '*/res/values/*strings.xml' \
     -print \
   | sed -n 's/.\///p' \
   | sort \
@@ -33,16 +34,16 @@
 # Scrape string.xml files for platform branch
 actual="$tempdir/actual.txt"
 grep 'androidx-platform-dev' "$exports" \
-  | grep -Eo '[^ ]+/strings\.xml' \
+  | grep -Eo '[^ ]+strings\.xml' \
   | sort \
   > "$actual"
 
 # Compare and report
 diff=$(diff "${expect}" "${actual}" | { grep '<' || true; })
 if [ -n "$diff" ]; then
-  echo "Missing files in $exports:" &> 2
-  diff "$expect" "$actual" | grep strings.xml | sed -n 's/< //p' &> 2
-  echo &> 2
-  echo 'See go/androidx/playbook#translations for more information' &> 2
+  echo "Missing files in $exports:" >&2
+  diff "$expect" "$actual" | grep strings.xml | sed -n 's/< //p' >&2
+  echo >&2
+  echo 'See go/androidx/playbook#translations for more information' >&2
   exit 1
 fi
diff --git a/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/validation/ExtensionValidationResultActivity.kt b/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/validation/ExtensionValidationResultActivity.kt
index c3a2051..89dbe9f 100644
--- a/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/validation/ExtensionValidationResultActivity.kt
+++ b/camera/integration-tests/extensionstestapp/src/main/java/androidx/camera/integration/extensions/validation/ExtensionValidationResultActivity.kt
@@ -48,7 +48,7 @@
     private val imageValidationActivityRequestCode =
         ImageValidationActivity::class.java.hashCode() % 1000
 
-    @Suppress("UNCHECKED_CAST")
+    @Suppress("UNCHECKED_CAST", "DEPRECATION")
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(R.layout.full_listview)
diff --git a/car/app/app-projected/src/test/java/androidx/car/app/hardware/common/CarResultStubMapTest.java b/car/app/app-projected/src/test/java/androidx/car/app/hardware/common/CarResultStubMapTest.java
index 04e9656..0b75733 100644
--- a/car/app/app-projected/src/test/java/androidx/car/app/hardware/common/CarResultStubMapTest.java
+++ b/car/app/app-projected/src/test/java/androidx/car/app/hardware/common/CarResultStubMapTest.java
@@ -121,7 +121,7 @@
         Integer desiredResult = 5;
         Bundleable desiredBundleable = Bundleable.create(desiredResult);
         int desiredResultType = ICarHardwareResultTypes.TYPE_SENSOR_ACCELEROMETER;
-        Integer unsupportedResult = new Integer(-1);
+        Integer unsupportedResult = -1;
         String param = "param";
         Bundleable paramBundle = Bundleable.create(param);
 
@@ -193,7 +193,7 @@
     public void addListener_multiple_listener_multiple_param() throws BundlerException,
             RemoteException {
         int desiredResultType = ICarHardwareResultTypes.TYPE_SENSOR_ACCELEROMETER;
-        Integer unsupportedResult = new Integer(-1);
+        Integer unsupportedResult = -1;
 
         CarResultStubMap<Integer, Integer> carResultStubMap = new CarResultStubMap<>(
                 desiredResultType,
diff --git a/car/app/app/src/main/java/androidx/car/app/notification/CarAppNotificationBroadcastReceiver.java b/car/app/app/src/main/java/androidx/car/app/notification/CarAppNotificationBroadcastReceiver.java
index 9a9bd33..49c96d4 100644
--- a/car/app/app/src/main/java/androidx/car/app/notification/CarAppNotificationBroadcastReceiver.java
+++ b/car/app/app/src/main/java/androidx/car/app/notification/CarAppNotificationBroadcastReceiver.java
@@ -47,6 +47,7 @@
 public class CarAppNotificationBroadcastReceiver extends BroadcastReceiver {
     private static final String TAG = LogTags.TAG + ".NBR";
 
+    @SuppressWarnings("deprecation")
     @Override
     public void onReceive(@NonNull Context context, @NonNull Intent intent) {
         ComponentName appComponent =
diff --git a/car/app/app/src/test/java/androidx/car/app/notification/CarPendingIntentTest.java b/car/app/app/src/test/java/androidx/car/app/notification/CarPendingIntentTest.java
index 5a03bb1..86daab0 100644
--- a/car/app/app/src/test/java/androidx/car/app/notification/CarPendingIntentTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/notification/CarPendingIntentTest.java
@@ -52,6 +52,7 @@
     private final ComponentName mComponentName = new ComponentName(mContext, CarAppService.class);
     private final Intent mIntent = new Intent("fooAction").setComponent(mComponentName);
 
+    @SuppressWarnings("deprecation")
     @Test
     public void getCarApp_returnsTheExpectedPendingIntent() throws PendingIntent.CanceledException {
         PendingIntent pendingIntent = CarPendingIntent.getCarApp(mContext, 1, mIntent,
diff --git a/compose/ui/ui-text/build.gradle b/compose/ui/ui-text/build.gradle
index fb042f5..659fb9c 100644
--- a/compose/ui/ui-text/build.gradle
+++ b/compose/ui/ui-text/build.gradle
@@ -43,7 +43,7 @@
         implementation("androidx.compose.runtime:runtime-saveable:1.1.1")
         implementation(project(":compose:ui:ui-util"))
         implementation(libs.kotlinStdlib)
-        implementation("androidx.core:core:1.5.0")
+        implementation("androidx.core:core:1.7.0")
         implementation('androidx.collection:collection:1.0.0')
 
         testImplementation(project(":compose:ui:ui-test-font"))
@@ -121,7 +121,7 @@
 
             androidMain.dependencies {
                 api("androidx.annotation:annotation:1.1.0")
-                implementation("androidx.core:core:1.5.0")
+                implementation("androidx.core:core:1.7.0")
                 implementation('androidx.collection:collection:1.0.0')
             }
 
diff --git a/core/core-animation-integration-tests/testapp/src/androidTest/java/androidx/core/animation/ObjectAnimatorTest.java b/core/core-animation-integration-tests/testapp/src/androidTest/java/androidx/core/animation/ObjectAnimatorTest.java
index f85edaa..aed16bd 100644
--- a/core/core-animation-integration-tests/testapp/src/androidTest/java/androidx/core/animation/ObjectAnimatorTest.java
+++ b/core/core-animation-integration-tests/testapp/src/androidTest/java/androidx/core/animation/ObjectAnimatorTest.java
@@ -312,7 +312,7 @@
         String propertyName = "backgroundColor";
         int startColor = Color.RED;
         int endColor = Color.BLUE;
-        Object[] values = {new Integer(startColor), new Integer(endColor)};
+        Object[] values = {startColor, endColor};
         ArgbEvaluator evaluator = ArgbEvaluator.getInstance();
         ObjectAnimator colorAnimator = ObjectAnimator.ofObject(object, propertyName,
                 evaluator, values);
@@ -360,7 +360,7 @@
         String propertyName = "backgroundColor";
         int startColor = Color.RED;
         int endColor = Color.BLUE;
-        Object[] values = {new Integer(startColor), new Integer(endColor)};
+        Object[] values = {startColor, endColor};
         ArgbEvaluator evaluator = ArgbEvaluator.getInstance();
         ObjectAnimator colorAnimator = ObjectAnimator.ofObject(object, propertyName,
                 evaluator, values);
diff --git a/core/core-appdigest/src/androidTest/java/androidx/core/appdigest/ChecksumsTest.java b/core/core-appdigest/src/androidTest/java/androidx/core/appdigest/ChecksumsTest.java
index d712487..fd87143 100644
--- a/core/core-appdigest/src/androidTest/java/androidx/core/appdigest/ChecksumsTest.java
+++ b/core/core-appdigest/src/androidTest/java/androidx/core/appdigest/ChecksumsTest.java
@@ -662,6 +662,7 @@
     @SdkSuppress(minSdkVersion = 29)
     @LargeTest
     @Test
+    @SuppressWarnings("deprecation")
     public void testFixedAllFileChecksumsSingleThread() throws Exception {
         installPackage(TEST_FIXED_APK);
         assertTrue(isAppInstalled(FIXED_PACKAGE_NAME));
@@ -951,6 +952,7 @@
                 trustedInstallers);
     }
 
+    @SuppressWarnings("deprecation")
     private Checksum[] getFileChecksums(@NonNull String packageName,
             @Checksum.Type int required, @NonNull List<Certificate> trustedInstallers)
             throws Exception {
@@ -1184,6 +1186,7 @@
             }
         }
 
+        @SuppressWarnings("deprecation")
         static Certificate getInstallerCertificate(Context context) throws Exception {
             PackageManager pm = context.getPackageManager();
             PackageInfo installerPackageInfo = pm.getPackageInfo(INSTALLER_PACKAGE_NAME,
diff --git a/core/core-ktx/api/1.8.0-beta01.txt b/core/core-ktx/api/1.8.0-beta01.txt
deleted file mode 100644
index 521f26c..0000000
--- a/core/core-ktx/api/1.8.0-beta01.txt
+++ /dev/null
@@ -1,629 +0,0 @@
-// Signature format: 4.0
-package androidx.core.animation {
-
-  public final class AnimatorKt {
-    method public static inline android.animation.Animator.AnimatorListener addListener(android.animation.Animator, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onEnd, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onStart, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onCancel, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onRepeat);
-    method @RequiresApi(19) public static inline android.animation.Animator.AnimatorPauseListener addPauseListener(android.animation.Animator, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onResume, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onPause);
-    method public static inline android.animation.Animator.AnimatorListener doOnCancel(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method public static inline android.animation.Animator.AnimatorListener doOnEnd(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.animation.Animator.AnimatorPauseListener doOnPause(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method public static inline android.animation.Animator.AnimatorListener doOnRepeat(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.animation.Animator.AnimatorPauseListener doOnResume(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method public static inline android.animation.Animator.AnimatorListener doOnStart(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-  }
-
-}
-
-package androidx.core.content {
-
-  public final class ContentValuesKt {
-    method public static android.content.ContentValues contentValuesOf(kotlin.Pair<java.lang.String,?>... pairs);
-  }
-
-  public final class ContextKt {
-    method public static inline <reified T> T! getSystemService(android.content.Context);
-    method public static inline void withStyledAttributes(android.content.Context, optional android.util.AttributeSet? set, int[] attrs, optional @AttrRes int defStyleAttr, optional @StyleRes int defStyleRes, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
-    method public static inline void withStyledAttributes(android.content.Context, @StyleRes int resourceId, int[] attrs, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
-  }
-
-  public final class SharedPreferencesKt {
-    method public static inline void edit(android.content.SharedPreferences, optional boolean commit, kotlin.jvm.functions.Function1<? super android.content.SharedPreferences.Editor,kotlin.Unit> action);
-  }
-
-}
-
-package androidx.core.content.res {
-
-  public final class TypedArrayKt {
-    method public static boolean getBooleanOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @ColorInt public static int getColorOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static android.content.res.ColorStateList getColorStateListOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static float getDimensionOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @Dimension public static int getDimensionPixelOffsetOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @Dimension public static int getDimensionPixelSizeOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static android.graphics.drawable.Drawable getDrawableOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static float getFloatOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @RequiresApi(26) public static android.graphics.Typeface getFontOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static int getIntOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static int getIntegerOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @AnyRes public static int getResourceIdOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static String getStringOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static CharSequence![] getTextArrayOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static CharSequence getTextOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static inline <R> R! use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
-  }
-
-}
-
-package androidx.core.database {
-
-  public final class CursorKt {
-    method public static inline byte[]? getBlobOrNull(android.database.Cursor, int index);
-    method public static inline Double? getDoubleOrNull(android.database.Cursor, int index);
-    method public static inline Float? getFloatOrNull(android.database.Cursor, int index);
-    method public static inline Integer? getIntOrNull(android.database.Cursor, int index);
-    method public static inline Long? getLongOrNull(android.database.Cursor, int index);
-    method public static inline Short? getShortOrNull(android.database.Cursor, int index);
-    method public static inline String? getStringOrNull(android.database.Cursor, int index);
-  }
-
-}
-
-package androidx.core.database.sqlite {
-
-  public final class SQLiteDatabaseKt {
-    method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
-  }
-
-}
-
-package androidx.core.graphics {
-
-  public final class BitmapKt {
-    method public static inline android.graphics.Bitmap applyCanvas(android.graphics.Bitmap, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline operator boolean contains(android.graphics.Bitmap, android.graphics.Point p);
-    method public static inline operator boolean contains(android.graphics.Bitmap, android.graphics.PointF p);
-    method public static inline android.graphics.Bitmap createBitmap(int width, int height, optional android.graphics.Bitmap.Config config);
-    method @RequiresApi(26) public static inline android.graphics.Bitmap createBitmap(int width, int height, optional android.graphics.Bitmap.Config config, optional boolean hasAlpha, optional android.graphics.ColorSpace colorSpace);
-    method public static inline operator int get(android.graphics.Bitmap, int x, int y);
-    method public static inline android.graphics.Bitmap scale(android.graphics.Bitmap, int width, int height, optional boolean filter);
-    method public static inline operator void set(android.graphics.Bitmap, int x, int y, @ColorInt int color);
-  }
-
-  public final class CanvasKt {
-    method public static inline void withClip(android.graphics.Canvas, android.graphics.Rect clipRect, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withClip(android.graphics.Canvas, android.graphics.RectF clipRect, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withClip(android.graphics.Canvas, int left, int top, int right, int bottom, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withClip(android.graphics.Canvas, float left, float top, float right, float bottom, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withClip(android.graphics.Canvas, android.graphics.Path clipPath, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withMatrix(android.graphics.Canvas, optional android.graphics.Matrix matrix, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withRotation(android.graphics.Canvas, optional float degrees, optional float pivotX, optional float pivotY, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withSave(android.graphics.Canvas, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withScale(android.graphics.Canvas, optional float x, optional float y, optional float pivotX, optional float pivotY, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withSkew(android.graphics.Canvas, optional float x, optional float y, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withTranslation(android.graphics.Canvas, optional float x, optional float y, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-  }
-
-  public final class ColorKt {
-    method @RequiresApi(26) public static inline operator float component1(android.graphics.Color);
-    method public static inline operator int component1(@ColorInt int);
-    method @RequiresApi(26) public static inline operator float component1(@ColorLong long);
-    method @RequiresApi(26) public static inline operator float component2(android.graphics.Color);
-    method public static inline operator int component2(@ColorInt int);
-    method @RequiresApi(26) public static inline operator float component2(@ColorLong long);
-    method @RequiresApi(26) public static inline operator float component3(android.graphics.Color);
-    method public static inline operator int component3(@ColorInt int);
-    method @RequiresApi(26) public static inline operator float component3(@ColorLong long);
-    method @RequiresApi(26) public static inline operator float component4(android.graphics.Color);
-    method public static inline operator int component4(@ColorInt int);
-    method @RequiresApi(26) public static inline operator float component4(@ColorLong long);
-    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorInt int, android.graphics.ColorSpace.Named colorSpace);
-    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorInt int, android.graphics.ColorSpace colorSpace);
-    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorLong long, android.graphics.ColorSpace.Named colorSpace);
-    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorLong long, android.graphics.ColorSpace colorSpace);
-    method @RequiresApi(26) public static inline infix android.graphics.Color convertTo(android.graphics.Color, android.graphics.ColorSpace.Named colorSpace);
-    method @RequiresApi(26) public static inline infix android.graphics.Color convertTo(android.graphics.Color, android.graphics.ColorSpace colorSpace);
-    method public static inline int getAlpha(@ColorInt int);
-    method @RequiresApi(26) public static inline float getAlpha(@ColorLong long);
-    method public static inline int getBlue(@ColorInt int);
-    method @RequiresApi(26) public static inline float getBlue(@ColorLong long);
-    method @RequiresApi(26) public static inline android.graphics.ColorSpace getColorSpace(@ColorLong long);
-    method public static inline int getGreen(@ColorInt int);
-    method @RequiresApi(26) public static inline float getGreen(@ColorLong long);
-    method @RequiresApi(26) public static inline float getLuminance(@ColorInt int);
-    method @RequiresApi(26) public static inline float getLuminance(@ColorLong long);
-    method public static inline int getRed(@ColorInt int);
-    method @RequiresApi(26) public static inline float getRed(@ColorLong long);
-    method @RequiresApi(26) public static inline boolean isSrgb(@ColorLong long);
-    method @RequiresApi(26) public static inline boolean isWideGamut(@ColorLong long);
-    method @RequiresApi(26) public static operator android.graphics.Color plus(android.graphics.Color, android.graphics.Color c);
-    method @RequiresApi(26) public static inline android.graphics.Color toColor(@ColorInt int);
-    method @RequiresApi(26) public static inline android.graphics.Color toColor(@ColorLong long);
-    method @ColorInt @RequiresApi(26) public static inline int toColorInt(@ColorLong long);
-    method @ColorInt public static inline int toColorInt(String);
-    method @ColorLong @RequiresApi(26) public static inline long toColorLong(@ColorInt int);
-  }
-
-  public final class ImageDecoderKt {
-    method @RequiresApi(28) public static inline android.graphics.Bitmap decodeBitmap(android.graphics.ImageDecoder.Source, kotlin.jvm.functions.Function3<? super android.graphics.ImageDecoder,? super android.graphics.ImageDecoder.ImageInfo,? super android.graphics.ImageDecoder.Source,kotlin.Unit> action);
-    method @RequiresApi(28) public static inline android.graphics.drawable.Drawable decodeDrawable(android.graphics.ImageDecoder.Source, kotlin.jvm.functions.Function3<? super android.graphics.ImageDecoder,? super android.graphics.ImageDecoder.ImageInfo,? super android.graphics.ImageDecoder.Source,kotlin.Unit> action);
-  }
-
-  public final class MatrixKt {
-    method public static android.graphics.Matrix rotationMatrix(float degrees, optional float px, optional float py);
-    method public static android.graphics.Matrix scaleMatrix(optional float sx, optional float sy);
-    method public static inline operator android.graphics.Matrix times(android.graphics.Matrix, android.graphics.Matrix m);
-    method public static android.graphics.Matrix translationMatrix(optional float tx, optional float ty);
-    method public static inline float[] values(android.graphics.Matrix);
-  }
-
-  public final class PaintKt {
-    method public static inline boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat? blendModeCompat);
-  }
-
-  public final class PathKt {
-    method @RequiresApi(19) public static inline infix android.graphics.Path and(android.graphics.Path, android.graphics.Path p);
-    method @RequiresApi(26) public static Iterable<androidx.core.graphics.PathSegment> flatten(android.graphics.Path, optional float error);
-    method @RequiresApi(19) public static inline operator android.graphics.Path minus(android.graphics.Path, android.graphics.Path p);
-    method @RequiresApi(19) public static inline infix android.graphics.Path or(android.graphics.Path, android.graphics.Path p);
-    method @RequiresApi(19) public static inline operator android.graphics.Path plus(android.graphics.Path, android.graphics.Path p);
-    method @RequiresApi(19) public static inline infix android.graphics.Path xor(android.graphics.Path, android.graphics.Path p);
-  }
-
-  public final class PictureKt {
-    method public static inline android.graphics.Picture record(android.graphics.Picture, int width, int height, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-  }
-
-  public final class PointKt {
-    method public static inline operator int component1(android.graphics.Point);
-    method public static inline operator float component1(android.graphics.PointF);
-    method public static inline operator int component2(android.graphics.Point);
-    method public static inline operator float component2(android.graphics.PointF);
-    method public static inline operator android.graphics.Point minus(android.graphics.Point, android.graphics.Point p);
-    method public static inline operator android.graphics.PointF minus(android.graphics.PointF, android.graphics.PointF p);
-    method public static inline operator android.graphics.Point minus(android.graphics.Point, int xy);
-    method public static inline operator android.graphics.PointF minus(android.graphics.PointF, float xy);
-    method public static inline operator android.graphics.Point plus(android.graphics.Point, android.graphics.Point p);
-    method public static inline operator android.graphics.PointF plus(android.graphics.PointF, android.graphics.PointF p);
-    method public static inline operator android.graphics.Point plus(android.graphics.Point, int xy);
-    method public static inline operator android.graphics.PointF plus(android.graphics.PointF, float xy);
-    method public static inline android.graphics.Point toPoint(android.graphics.PointF);
-    method public static inline android.graphics.PointF toPointF(android.graphics.Point);
-    method public static inline operator android.graphics.Point unaryMinus(android.graphics.Point);
-    method public static inline operator android.graphics.PointF unaryMinus(android.graphics.PointF);
-  }
-
-  public final class PorterDuffKt {
-    method public static inline android.graphics.PorterDuffColorFilter toColorFilter(android.graphics.PorterDuff.Mode, int color);
-    method public static inline android.graphics.PorterDuffXfermode toXfermode(android.graphics.PorterDuff.Mode);
-  }
-
-  public final class RectKt {
-    method public static inline infix android.graphics.Rect and(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline infix android.graphics.RectF and(android.graphics.RectF, android.graphics.RectF r);
-    method public static inline operator int component1(android.graphics.Rect);
-    method public static inline operator float component1(android.graphics.RectF);
-    method public static inline operator int component2(android.graphics.Rect);
-    method public static inline operator float component2(android.graphics.RectF);
-    method public static inline operator int component3(android.graphics.Rect);
-    method public static inline operator float component3(android.graphics.RectF);
-    method public static inline operator int component4(android.graphics.Rect);
-    method public static inline operator float component4(android.graphics.RectF);
-    method public static inline operator boolean contains(android.graphics.Rect, android.graphics.Point p);
-    method public static inline operator boolean contains(android.graphics.RectF, android.graphics.PointF p);
-    method public static inline operator android.graphics.Region minus(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline operator android.graphics.Region minus(android.graphics.RectF, android.graphics.RectF r);
-    method public static inline operator android.graphics.Rect minus(android.graphics.Rect, int xy);
-    method public static inline operator android.graphics.RectF minus(android.graphics.RectF, float xy);
-    method public static inline operator android.graphics.Rect minus(android.graphics.Rect, android.graphics.Point xy);
-    method public static inline operator android.graphics.RectF minus(android.graphics.RectF, android.graphics.PointF xy);
-    method public static inline infix android.graphics.Rect or(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline infix android.graphics.RectF or(android.graphics.RectF, android.graphics.RectF r);
-    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, android.graphics.RectF r);
-    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, int xy);
-    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, float xy);
-    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, android.graphics.Point xy);
-    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, android.graphics.PointF xy);
-    method public static inline operator android.graphics.Rect times(android.graphics.Rect, int factor);
-    method public static inline operator android.graphics.RectF times(android.graphics.RectF, int factor);
-    method public static inline operator android.graphics.RectF times(android.graphics.RectF, float factor);
-    method public static inline android.graphics.Rect toRect(android.graphics.RectF);
-    method public static inline android.graphics.RectF toRectF(android.graphics.Rect);
-    method public static inline android.graphics.Region toRegion(android.graphics.Rect);
-    method public static inline android.graphics.Region toRegion(android.graphics.RectF);
-    method public static inline android.graphics.RectF transform(android.graphics.RectF, android.graphics.Matrix m);
-    method public static inline infix android.graphics.Region xor(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline infix android.graphics.Region xor(android.graphics.RectF, android.graphics.RectF r);
-  }
-
-  public final class RegionKt {
-    method public static inline infix android.graphics.Region and(android.graphics.Region, android.graphics.Rect r);
-    method public static inline infix android.graphics.Region and(android.graphics.Region, android.graphics.Region r);
-    method public static inline operator boolean contains(android.graphics.Region, android.graphics.Point p);
-    method public static inline void forEach(android.graphics.Region, kotlin.jvm.functions.Function1<? super android.graphics.Rect,kotlin.Unit> action);
-    method public static operator java.util.Iterator<android.graphics.Rect> iterator(android.graphics.Region);
-    method public static inline operator android.graphics.Region minus(android.graphics.Region, android.graphics.Rect r);
-    method public static inline operator android.graphics.Region minus(android.graphics.Region, android.graphics.Region r);
-    method public static inline operator android.graphics.Region not(android.graphics.Region);
-    method public static inline infix android.graphics.Region or(android.graphics.Region, android.graphics.Rect r);
-    method public static inline infix android.graphics.Region or(android.graphics.Region, android.graphics.Region r);
-    method public static inline operator android.graphics.Region plus(android.graphics.Region, android.graphics.Rect r);
-    method public static inline operator android.graphics.Region plus(android.graphics.Region, android.graphics.Region r);
-    method public static inline operator android.graphics.Region unaryMinus(android.graphics.Region);
-    method public static inline infix android.graphics.Region xor(android.graphics.Region, android.graphics.Rect r);
-    method public static inline infix android.graphics.Region xor(android.graphics.Region, android.graphics.Region r);
-  }
-
-  public final class ShaderKt {
-    method public static inline void transform(android.graphics.Shader, kotlin.jvm.functions.Function1<? super android.graphics.Matrix,kotlin.Unit> block);
-  }
-
-}
-
-package androidx.core.graphics.drawable {
-
-  public final class BitmapDrawableKt {
-    method public static inline android.graphics.drawable.BitmapDrawable toDrawable(android.graphics.Bitmap, android.content.res.Resources resources);
-  }
-
-  public final class ColorDrawableKt {
-    method public static inline android.graphics.drawable.ColorDrawable toDrawable(@ColorInt int);
-    method @RequiresApi(26) public static inline android.graphics.drawable.ColorDrawable toDrawable(android.graphics.Color);
-  }
-
-  public final class DrawableKt {
-    method public static android.graphics.Bitmap toBitmap(android.graphics.drawable.Drawable, optional @Px int width, optional @Px int height, optional android.graphics.Bitmap.Config? config);
-    method public static android.graphics.Bitmap? toBitmapOrNull(android.graphics.drawable.Drawable, optional @Px int width, optional @Px int height, optional android.graphics.Bitmap.Config? config);
-    method public static void updateBounds(android.graphics.drawable.Drawable, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
-  }
-
-  public final class IconKt {
-    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toAdaptiveIcon(android.graphics.Bitmap);
-    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(android.graphics.Bitmap);
-    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(android.net.Uri);
-    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(byte[]);
-  }
-
-}
-
-package androidx.core.location {
-
-  public final class LocationKt {
-    method public static inline operator double component1(android.location.Location);
-    method public static inline operator double component2(android.location.Location);
-  }
-
-}
-
-package androidx.core.net {
-
-  public final class UriKt {
-    method public static java.io.File toFile(android.net.Uri);
-    method public static inline android.net.Uri toUri(String);
-    method public static inline android.net.Uri toUri(java.io.File);
-  }
-
-}
-
-package androidx.core.os {
-
-  public final class BundleKt {
-    method public static android.os.Bundle bundleOf(kotlin.Pair<java.lang.String,?>... pairs);
-    method public static android.os.Bundle bundleOf();
-  }
-
-  public final class HandlerKt {
-    method public static inline Runnable postAtTime(android.os.Handler, long uptimeMillis, optional Object? token, kotlin.jvm.functions.Function0<kotlin.Unit> action);
-    method public static inline Runnable postDelayed(android.os.Handler, long delayInMillis, optional Object? token, kotlin.jvm.functions.Function0<kotlin.Unit> action);
-  }
-
-  @RequiresApi(31) public final class OutcomeReceiverKt {
-    method @RequiresApi(31) public static <R, E extends java.lang.Throwable> android.os.OutcomeReceiver<R,E> asOutcomeReceiver(kotlin.coroutines.Continuation<? super R>);
-  }
-
-  public final class PersistableBundleKt {
-    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf(kotlin.Pair<java.lang.String,?>... pairs);
-    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf();
-    method @RequiresApi(21) public static android.os.PersistableBundle toPersistableBundle(java.util.Map<java.lang.String,?>);
-  }
-
-  public final class TraceKt {
-    method @Deprecated public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
-  }
-
-}
-
-package androidx.core.text {
-
-  public final class CharSequenceKt {
-    method public static inline boolean isDigitsOnly(CharSequence);
-    method public static inline int trimmedLength(CharSequence);
-  }
-
-  public final class HtmlKt {
-    method public static inline android.text.Spanned parseAsHtml(String, optional int flags, optional android.text.Html.ImageGetter? imageGetter, optional android.text.Html.TagHandler? tagHandler);
-    method public static inline String toHtml(android.text.Spanned, optional int option);
-  }
-
-  public final class LocaleKt {
-    method @RequiresApi(17) public static inline int getLayoutDirection(java.util.Locale);
-  }
-
-  public final class SpannableStringBuilderKt {
-    method public static inline android.text.SpannableStringBuilder backgroundColor(android.text.SpannableStringBuilder, @ColorInt int color, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder bold(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannedString buildSpannedString(kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder color(android.text.SpannableStringBuilder, @ColorInt int color, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder inSpans(android.text.SpannableStringBuilder, Object![] spans, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder inSpans(android.text.SpannableStringBuilder, Object span, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder italic(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder scale(android.text.SpannableStringBuilder, float proportion, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder strikeThrough(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder subscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder superscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder underline(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-  }
-
-  public final class SpannableStringKt {
-    method public static inline void clearSpans(android.text.Spannable);
-    method public static inline operator void set(android.text.Spannable, int start, int end, Object span);
-    method public static inline operator void set(android.text.Spannable, kotlin.ranges.IntRange range, Object span);
-    method public static inline android.text.Spannable toSpannable(CharSequence);
-  }
-
-  public final class SpannedStringKt {
-    method public static inline <reified T> T![]! getSpans(android.text.Spanned, optional int start, optional int end);
-    method public static inline android.text.Spanned toSpanned(CharSequence);
-  }
-
-  public final class StringKt {
-    method public static inline String htmlEncode(String);
-  }
-
-}
-
-package androidx.core.transition {
-
-  public final class TransitionKt {
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener addListener(android.transition.Transition, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onEnd, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onStart, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onCancel, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onResume, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onPause);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnCancel(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnEnd(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnPause(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnResume(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnStart(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-  }
-
-}
-
-package androidx.core.util {
-
-  public final class AndroidXConsumerKt {
-    method public static <T> androidx.core.util.Consumer<T> asAndroidXConsumer(kotlin.coroutines.Continuation<? super T>);
-  }
-
-  public final class AtomicFileKt {
-    method @RequiresApi(17) public static inline byte[] readBytes(android.util.AtomicFile);
-    method @RequiresApi(17) public static String readText(android.util.AtomicFile, optional java.nio.charset.Charset charset);
-    method @RequiresApi(17) public static inline void tryWrite(android.util.AtomicFile, kotlin.jvm.functions.Function1<? super java.io.FileOutputStream,kotlin.Unit> block);
-    method @RequiresApi(17) public static void writeBytes(android.util.AtomicFile, byte[] array);
-    method @RequiresApi(17) public static void writeText(android.util.AtomicFile, String text, optional java.nio.charset.Charset charset);
-  }
-
-  @RequiresApi(24) public final class ConsumerKt {
-    method @RequiresApi(24) public static <T> java.util.function.Consumer<T> asConsumer(kotlin.coroutines.Continuation<? super T>);
-  }
-
-  public final class HalfKt {
-    method @RequiresApi(26) public static inline android.util.Half toHalf(@HalfFloat short);
-    method @RequiresApi(26) public static inline android.util.Half toHalf(float);
-    method @RequiresApi(26) public static inline android.util.Half toHalf(double);
-    method @RequiresApi(26) public static inline android.util.Half toHalf(String);
-  }
-
-  public final class LongSparseArrayKt {
-    method @RequiresApi(16) public static inline operator <T> boolean contains(android.util.LongSparseArray<T>, long key);
-    method @RequiresApi(16) public static inline <T> boolean containsKey(android.util.LongSparseArray<T>, long key);
-    method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T? value);
-    method @RequiresApi(16) public static inline <T> void forEach(android.util.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
-    method @RequiresApi(16) public static inline <T> T! getOrDefault(android.util.LongSparseArray<T>, long key, T? defaultValue);
-    method @RequiresApi(16) public static inline <T> T! getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
-    method @RequiresApi(16) public static inline <T> int getSize(android.util.LongSparseArray<T>);
-    method @RequiresApi(16) public static inline <T> boolean isEmpty(android.util.LongSparseArray<T>);
-    method @RequiresApi(16) public static inline <T> boolean isNotEmpty(android.util.LongSparseArray<T>);
-    method @RequiresApi(16) public static <T> kotlin.collections.LongIterator keyIterator(android.util.LongSparseArray<T>);
-    method @RequiresApi(16) public static operator <T> android.util.LongSparseArray<T> plus(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
-    method @RequiresApi(16) public static <T> void putAll(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
-    method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T? value);
-    method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T? value);
-    method @RequiresApi(16) public static <T> java.util.Iterator<T> valueIterator(android.util.LongSparseArray<T>);
-  }
-
-  public final class LruCacheKt {
-    method public static inline <K, V> android.util.LruCache<K,V> lruCache(int maxSize, optional kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Integer> sizeOf, optional kotlin.jvm.functions.Function1<? super K,? extends V> create, optional kotlin.jvm.functions.Function4<? super java.lang.Boolean,? super K,? super V,? super V,kotlin.Unit> onEntryRemoved);
-  }
-
-  public final class PairKt {
-    method public static inline operator <F, S> F! component1(androidx.core.util.Pair<F,S>);
-    method public static inline operator <F, S> F! component1(android.util.Pair<F,S>);
-    method public static inline operator <F, S> S! component2(androidx.core.util.Pair<F,S>);
-    method public static inline operator <F, S> S! component2(android.util.Pair<F,S>);
-    method public static inline <F, S> android.util.Pair<F,S> toAndroidPair(kotlin.Pair<? extends F,? extends S>);
-    method public static inline <F, S> androidx.core.util.Pair<F,S> toAndroidXPair(kotlin.Pair<? extends F,? extends S>);
-    method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(androidx.core.util.Pair<F,S>);
-    method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(android.util.Pair<F,S>);
-  }
-
-  public final class RangeKt {
-    method @RequiresApi(21) public static inline infix <T extends java.lang.Comparable<? super T>> android.util.Range<T> and(android.util.Range<T>, android.util.Range<T> other);
-    method @RequiresApi(21) public static inline operator <T extends java.lang.Comparable<? super T>> android.util.Range<T> plus(android.util.Range<T>, T value);
-    method @RequiresApi(21) public static inline operator <T extends java.lang.Comparable<? super T>> android.util.Range<T> plus(android.util.Range<T>, android.util.Range<T> other);
-    method @RequiresApi(21) public static inline infix <T extends java.lang.Comparable<? super T>> android.util.Range<T> rangeTo(T, T that);
-    method @RequiresApi(21) public static <T extends java.lang.Comparable<? super T>> kotlin.ranges.ClosedRange<T> toClosedRange(android.util.Range<T>);
-    method @RequiresApi(21) public static <T extends java.lang.Comparable<? super T>> android.util.Range<T> toRange(kotlin.ranges.ClosedRange<T>);
-  }
-
-  public final class RunnableKt {
-    method public static Runnable asRunnable(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-  }
-
-  public final class SizeKt {
-    method @RequiresApi(21) public static inline operator int component1(android.util.Size);
-    method @RequiresApi(21) public static inline operator float component1(android.util.SizeF);
-    method public static inline operator float component1(androidx.core.util.SizeFCompat);
-    method @RequiresApi(21) public static inline operator int component2(android.util.Size);
-    method @RequiresApi(21) public static inline operator float component2(android.util.SizeF);
-    method public static inline operator float component2(androidx.core.util.SizeFCompat);
-  }
-
-  public final class SparseArrayKt {
-    method public static inline operator <T> boolean contains(android.util.SparseArray<T>, int key);
-    method public static inline <T> boolean containsKey(android.util.SparseArray<T>, int key);
-    method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T? value);
-    method public static inline <T> void forEach(android.util.SparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
-    method public static inline <T> T! getOrDefault(android.util.SparseArray<T>, int key, T? defaultValue);
-    method public static inline <T> T! getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
-    method public static inline <T> int getSize(android.util.SparseArray<T>);
-    method public static inline <T> boolean isEmpty(android.util.SparseArray<T>);
-    method public static inline <T> boolean isNotEmpty(android.util.SparseArray<T>);
-    method public static <T> kotlin.collections.IntIterator keyIterator(android.util.SparseArray<T>);
-    method public static operator <T> android.util.SparseArray<T> plus(android.util.SparseArray<T>, android.util.SparseArray<T> other);
-    method public static <T> void putAll(android.util.SparseArray<T>, android.util.SparseArray<T> other);
-    method public static <T> boolean remove(android.util.SparseArray<T>, int key, T? value);
-    method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T? value);
-    method public static <T> java.util.Iterator<T> valueIterator(android.util.SparseArray<T>);
-  }
-
-  public final class SparseBooleanArrayKt {
-    method public static inline operator boolean contains(android.util.SparseBooleanArray, int key);
-    method public static inline boolean containsKey(android.util.SparseBooleanArray, int key);
-    method public static inline boolean containsValue(android.util.SparseBooleanArray, boolean value);
-    method public static inline void forEach(android.util.SparseBooleanArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Boolean,kotlin.Unit> action);
-    method public static inline boolean getOrDefault(android.util.SparseBooleanArray, int key, boolean defaultValue);
-    method public static inline boolean getOrElse(android.util.SparseBooleanArray, int key, kotlin.jvm.functions.Function0<java.lang.Boolean> defaultValue);
-    method public static inline int getSize(android.util.SparseBooleanArray);
-    method public static inline boolean isEmpty(android.util.SparseBooleanArray);
-    method public static inline boolean isNotEmpty(android.util.SparseBooleanArray);
-    method public static kotlin.collections.IntIterator keyIterator(android.util.SparseBooleanArray);
-    method public static operator android.util.SparseBooleanArray plus(android.util.SparseBooleanArray, android.util.SparseBooleanArray other);
-    method public static void putAll(android.util.SparseBooleanArray, android.util.SparseBooleanArray other);
-    method public static boolean remove(android.util.SparseBooleanArray, int key, boolean value);
-    method public static inline operator void set(android.util.SparseBooleanArray, int key, boolean value);
-    method public static kotlin.collections.BooleanIterator valueIterator(android.util.SparseBooleanArray);
-  }
-
-  public final class SparseIntArrayKt {
-    method public static inline operator boolean contains(android.util.SparseIntArray, int key);
-    method public static inline boolean containsKey(android.util.SparseIntArray, int key);
-    method public static inline boolean containsValue(android.util.SparseIntArray, int value);
-    method public static inline void forEach(android.util.SparseIntArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
-    method public static inline int getOrDefault(android.util.SparseIntArray, int key, int defaultValue);
-    method public static inline int getOrElse(android.util.SparseIntArray, int key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
-    method public static inline int getSize(android.util.SparseIntArray);
-    method public static inline boolean isEmpty(android.util.SparseIntArray);
-    method public static inline boolean isNotEmpty(android.util.SparseIntArray);
-    method public static kotlin.collections.IntIterator keyIterator(android.util.SparseIntArray);
-    method public static operator android.util.SparseIntArray plus(android.util.SparseIntArray, android.util.SparseIntArray other);
-    method public static void putAll(android.util.SparseIntArray, android.util.SparseIntArray other);
-    method public static boolean remove(android.util.SparseIntArray, int key, int value);
-    method public static inline operator void set(android.util.SparseIntArray, int key, int value);
-    method public static kotlin.collections.IntIterator valueIterator(android.util.SparseIntArray);
-  }
-
-  public final class SparseLongArrayKt {
-    method @RequiresApi(18) public static inline operator boolean contains(android.util.SparseLongArray, int key);
-    method @RequiresApi(18) public static inline boolean containsKey(android.util.SparseLongArray, int key);
-    method @RequiresApi(18) public static inline boolean containsValue(android.util.SparseLongArray, long value);
-    method @RequiresApi(18) public static inline void forEach(android.util.SparseLongArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,kotlin.Unit> action);
-    method @RequiresApi(18) public static inline long getOrDefault(android.util.SparseLongArray, int key, long defaultValue);
-    method @RequiresApi(18) public static inline long getOrElse(android.util.SparseLongArray, int key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
-    method @RequiresApi(18) public static inline int getSize(android.util.SparseLongArray);
-    method @RequiresApi(18) public static inline boolean isEmpty(android.util.SparseLongArray);
-    method @RequiresApi(18) public static inline boolean isNotEmpty(android.util.SparseLongArray);
-    method @RequiresApi(18) public static kotlin.collections.IntIterator keyIterator(android.util.SparseLongArray);
-    method @RequiresApi(18) public static operator android.util.SparseLongArray plus(android.util.SparseLongArray, android.util.SparseLongArray other);
-    method @RequiresApi(18) public static void putAll(android.util.SparseLongArray, android.util.SparseLongArray other);
-    method @RequiresApi(18) public static boolean remove(android.util.SparseLongArray, int key, long value);
-    method @RequiresApi(18) public static inline operator void set(android.util.SparseLongArray, int key, long value);
-    method @RequiresApi(18) public static kotlin.collections.LongIterator valueIterator(android.util.SparseLongArray);
-  }
-
-}
-
-package androidx.core.view {
-
-  public final class MenuKt {
-    method public static operator boolean contains(android.view.Menu, android.view.MenuItem item);
-    method public static inline void forEach(android.view.Menu, kotlin.jvm.functions.Function1<? super android.view.MenuItem,kotlin.Unit> action);
-    method public static inline void forEachIndexed(android.view.Menu, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.view.MenuItem,kotlin.Unit> action);
-    method public static inline operator android.view.MenuItem get(android.view.Menu, int index);
-    method public static kotlin.sequences.Sequence<android.view.MenuItem> getChildren(android.view.Menu);
-    method public static inline int getSize(android.view.Menu);
-    method public static inline boolean isEmpty(android.view.Menu);
-    method public static inline boolean isNotEmpty(android.view.Menu);
-    method public static operator java.util.Iterator<android.view.MenuItem> iterator(android.view.Menu);
-    method public static inline operator void minusAssign(android.view.Menu, android.view.MenuItem item);
-  }
-
-  public final class ViewGroupKt {
-    method public static inline operator boolean contains(android.view.ViewGroup, android.view.View view);
-    method public static inline void forEach(android.view.ViewGroup, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline void forEachIndexed(android.view.ViewGroup, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.view.View,kotlin.Unit> action);
-    method public static operator android.view.View get(android.view.ViewGroup, int index);
-    method public static kotlin.sequences.Sequence<android.view.View> getChildren(android.view.ViewGroup);
-    method public static kotlin.sequences.Sequence<android.view.View> getDescendants(android.view.ViewGroup);
-    method public static inline kotlin.ranges.IntRange getIndices(android.view.ViewGroup);
-    method public static inline int getSize(android.view.ViewGroup);
-    method public static inline boolean isEmpty(android.view.ViewGroup);
-    method public static inline boolean isNotEmpty(android.view.ViewGroup);
-    method public static operator java.util.Iterator<android.view.View> iterator(android.view.ViewGroup);
-    method public static inline operator void minusAssign(android.view.ViewGroup, android.view.View view);
-    method public static inline operator void plusAssign(android.view.ViewGroup, android.view.View view);
-    method public static inline void setMargins(android.view.ViewGroup.MarginLayoutParams, @Px int size);
-    method public static inline void updateMargins(android.view.ViewGroup.MarginLayoutParams, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
-    method @RequiresApi(17) public static inline void updateMarginsRelative(android.view.ViewGroup.MarginLayoutParams, optional @Px int start, optional @Px int top, optional @Px int end, optional @Px int bottom);
-  }
-
-  public final class ViewKt {
-    method public static inline void doOnAttach(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline void doOnDetach(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline void doOnLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline void doOnNextLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline androidx.core.view.OneShotPreDrawListener doOnPreDraw(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static android.graphics.Bitmap drawToBitmap(android.view.View, optional android.graphics.Bitmap.Config config);
-    method public static kotlin.sequences.Sequence<android.view.View> getAllViews(android.view.View);
-    method public static kotlin.sequences.Sequence<android.view.ViewParent> getAncestors(android.view.View);
-    method public static inline int getMarginBottom(android.view.View);
-    method public static inline int getMarginEnd(android.view.View);
-    method public static inline int getMarginLeft(android.view.View);
-    method public static inline int getMarginRight(android.view.View);
-    method public static inline int getMarginStart(android.view.View);
-    method public static inline int getMarginTop(android.view.View);
-    method public static inline boolean isGone(android.view.View);
-    method public static inline boolean isInvisible(android.view.View);
-    method public static inline boolean isVisible(android.view.View);
-    method public static inline Runnable postDelayed(android.view.View, long delayInMillis, kotlin.jvm.functions.Function0<kotlin.Unit> action);
-    method @RequiresApi(16) public static inline Runnable postOnAnimationDelayed(android.view.View, long delayInMillis, kotlin.jvm.functions.Function0<kotlin.Unit> action);
-    method public static inline void setGone(android.view.View, boolean);
-    method public static inline void setInvisible(android.view.View, boolean);
-    method public static inline void setPadding(android.view.View, @Px int size);
-    method public static inline void setVisible(android.view.View, boolean);
-    method public static inline void updateLayoutParams(android.view.View, kotlin.jvm.functions.Function1<? super android.view.ViewGroup.LayoutParams,kotlin.Unit> block);
-    method public static inline <reified T extends android.view.ViewGroup.LayoutParams> void updateLayoutParams(android.view.View, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> block);
-    method public static inline void updatePadding(android.view.View, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
-    method @RequiresApi(17) public static inline void updatePaddingRelative(android.view.View, optional @Px int start, optional @Px int top, optional @Px int end, optional @Px int bottom);
-  }
-
-}
-
-package androidx.core.widget {
-
-  public final class TextViewKt {
-    method public static inline android.text.TextWatcher addTextChangedListener(android.widget.TextView, optional kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> beforeTextChanged, optional kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> onTextChanged, optional kotlin.jvm.functions.Function1<? super android.text.Editable,kotlin.Unit> afterTextChanged);
-    method public static inline android.text.TextWatcher doAfterTextChanged(android.widget.TextView, kotlin.jvm.functions.Function1<? super android.text.Editable,kotlin.Unit> action);
-    method public static inline android.text.TextWatcher doBeforeTextChanged(android.widget.TextView, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
-    method public static inline android.text.TextWatcher doOnTextChanged(android.widget.TextView, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
-  }
-
-}
-
diff --git a/core/core-ktx/api/public_plus_experimental_1.8.0-beta01.txt b/core/core-ktx/api/public_plus_experimental_1.8.0-beta01.txt
deleted file mode 100644
index 521f26c..0000000
--- a/core/core-ktx/api/public_plus_experimental_1.8.0-beta01.txt
+++ /dev/null
@@ -1,629 +0,0 @@
-// Signature format: 4.0
-package androidx.core.animation {
-
-  public final class AnimatorKt {
-    method public static inline android.animation.Animator.AnimatorListener addListener(android.animation.Animator, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onEnd, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onStart, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onCancel, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onRepeat);
-    method @RequiresApi(19) public static inline android.animation.Animator.AnimatorPauseListener addPauseListener(android.animation.Animator, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onResume, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onPause);
-    method public static inline android.animation.Animator.AnimatorListener doOnCancel(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method public static inline android.animation.Animator.AnimatorListener doOnEnd(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.animation.Animator.AnimatorPauseListener doOnPause(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method public static inline android.animation.Animator.AnimatorListener doOnRepeat(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.animation.Animator.AnimatorPauseListener doOnResume(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method public static inline android.animation.Animator.AnimatorListener doOnStart(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-  }
-
-}
-
-package androidx.core.content {
-
-  public final class ContentValuesKt {
-    method public static android.content.ContentValues contentValuesOf(kotlin.Pair<java.lang.String,?>... pairs);
-  }
-
-  public final class ContextKt {
-    method public static inline <reified T> T! getSystemService(android.content.Context);
-    method public static inline void withStyledAttributes(android.content.Context, optional android.util.AttributeSet? set, int[] attrs, optional @AttrRes int defStyleAttr, optional @StyleRes int defStyleRes, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
-    method public static inline void withStyledAttributes(android.content.Context, @StyleRes int resourceId, int[] attrs, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
-  }
-
-  public final class SharedPreferencesKt {
-    method public static inline void edit(android.content.SharedPreferences, optional boolean commit, kotlin.jvm.functions.Function1<? super android.content.SharedPreferences.Editor,kotlin.Unit> action);
-  }
-
-}
-
-package androidx.core.content.res {
-
-  public final class TypedArrayKt {
-    method public static boolean getBooleanOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @ColorInt public static int getColorOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static android.content.res.ColorStateList getColorStateListOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static float getDimensionOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @Dimension public static int getDimensionPixelOffsetOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @Dimension public static int getDimensionPixelSizeOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static android.graphics.drawable.Drawable getDrawableOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static float getFloatOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @RequiresApi(26) public static android.graphics.Typeface getFontOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static int getIntOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static int getIntegerOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @AnyRes public static int getResourceIdOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static String getStringOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static CharSequence![] getTextArrayOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static CharSequence getTextOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static inline <R> R! use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
-  }
-
-}
-
-package androidx.core.database {
-
-  public final class CursorKt {
-    method public static inline byte[]? getBlobOrNull(android.database.Cursor, int index);
-    method public static inline Double? getDoubleOrNull(android.database.Cursor, int index);
-    method public static inline Float? getFloatOrNull(android.database.Cursor, int index);
-    method public static inline Integer? getIntOrNull(android.database.Cursor, int index);
-    method public static inline Long? getLongOrNull(android.database.Cursor, int index);
-    method public static inline Short? getShortOrNull(android.database.Cursor, int index);
-    method public static inline String? getStringOrNull(android.database.Cursor, int index);
-  }
-
-}
-
-package androidx.core.database.sqlite {
-
-  public final class SQLiteDatabaseKt {
-    method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
-  }
-
-}
-
-package androidx.core.graphics {
-
-  public final class BitmapKt {
-    method public static inline android.graphics.Bitmap applyCanvas(android.graphics.Bitmap, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline operator boolean contains(android.graphics.Bitmap, android.graphics.Point p);
-    method public static inline operator boolean contains(android.graphics.Bitmap, android.graphics.PointF p);
-    method public static inline android.graphics.Bitmap createBitmap(int width, int height, optional android.graphics.Bitmap.Config config);
-    method @RequiresApi(26) public static inline android.graphics.Bitmap createBitmap(int width, int height, optional android.graphics.Bitmap.Config config, optional boolean hasAlpha, optional android.graphics.ColorSpace colorSpace);
-    method public static inline operator int get(android.graphics.Bitmap, int x, int y);
-    method public static inline android.graphics.Bitmap scale(android.graphics.Bitmap, int width, int height, optional boolean filter);
-    method public static inline operator void set(android.graphics.Bitmap, int x, int y, @ColorInt int color);
-  }
-
-  public final class CanvasKt {
-    method public static inline void withClip(android.graphics.Canvas, android.graphics.Rect clipRect, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withClip(android.graphics.Canvas, android.graphics.RectF clipRect, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withClip(android.graphics.Canvas, int left, int top, int right, int bottom, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withClip(android.graphics.Canvas, float left, float top, float right, float bottom, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withClip(android.graphics.Canvas, android.graphics.Path clipPath, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withMatrix(android.graphics.Canvas, optional android.graphics.Matrix matrix, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withRotation(android.graphics.Canvas, optional float degrees, optional float pivotX, optional float pivotY, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withSave(android.graphics.Canvas, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withScale(android.graphics.Canvas, optional float x, optional float y, optional float pivotX, optional float pivotY, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withSkew(android.graphics.Canvas, optional float x, optional float y, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withTranslation(android.graphics.Canvas, optional float x, optional float y, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-  }
-
-  public final class ColorKt {
-    method @RequiresApi(26) public static inline operator float component1(android.graphics.Color);
-    method public static inline operator int component1(@ColorInt int);
-    method @RequiresApi(26) public static inline operator float component1(@ColorLong long);
-    method @RequiresApi(26) public static inline operator float component2(android.graphics.Color);
-    method public static inline operator int component2(@ColorInt int);
-    method @RequiresApi(26) public static inline operator float component2(@ColorLong long);
-    method @RequiresApi(26) public static inline operator float component3(android.graphics.Color);
-    method public static inline operator int component3(@ColorInt int);
-    method @RequiresApi(26) public static inline operator float component3(@ColorLong long);
-    method @RequiresApi(26) public static inline operator float component4(android.graphics.Color);
-    method public static inline operator int component4(@ColorInt int);
-    method @RequiresApi(26) public static inline operator float component4(@ColorLong long);
-    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorInt int, android.graphics.ColorSpace.Named colorSpace);
-    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorInt int, android.graphics.ColorSpace colorSpace);
-    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorLong long, android.graphics.ColorSpace.Named colorSpace);
-    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorLong long, android.graphics.ColorSpace colorSpace);
-    method @RequiresApi(26) public static inline infix android.graphics.Color convertTo(android.graphics.Color, android.graphics.ColorSpace.Named colorSpace);
-    method @RequiresApi(26) public static inline infix android.graphics.Color convertTo(android.graphics.Color, android.graphics.ColorSpace colorSpace);
-    method public static inline int getAlpha(@ColorInt int);
-    method @RequiresApi(26) public static inline float getAlpha(@ColorLong long);
-    method public static inline int getBlue(@ColorInt int);
-    method @RequiresApi(26) public static inline float getBlue(@ColorLong long);
-    method @RequiresApi(26) public static inline android.graphics.ColorSpace getColorSpace(@ColorLong long);
-    method public static inline int getGreen(@ColorInt int);
-    method @RequiresApi(26) public static inline float getGreen(@ColorLong long);
-    method @RequiresApi(26) public static inline float getLuminance(@ColorInt int);
-    method @RequiresApi(26) public static inline float getLuminance(@ColorLong long);
-    method public static inline int getRed(@ColorInt int);
-    method @RequiresApi(26) public static inline float getRed(@ColorLong long);
-    method @RequiresApi(26) public static inline boolean isSrgb(@ColorLong long);
-    method @RequiresApi(26) public static inline boolean isWideGamut(@ColorLong long);
-    method @RequiresApi(26) public static operator android.graphics.Color plus(android.graphics.Color, android.graphics.Color c);
-    method @RequiresApi(26) public static inline android.graphics.Color toColor(@ColorInt int);
-    method @RequiresApi(26) public static inline android.graphics.Color toColor(@ColorLong long);
-    method @ColorInt @RequiresApi(26) public static inline int toColorInt(@ColorLong long);
-    method @ColorInt public static inline int toColorInt(String);
-    method @ColorLong @RequiresApi(26) public static inline long toColorLong(@ColorInt int);
-  }
-
-  public final class ImageDecoderKt {
-    method @RequiresApi(28) public static inline android.graphics.Bitmap decodeBitmap(android.graphics.ImageDecoder.Source, kotlin.jvm.functions.Function3<? super android.graphics.ImageDecoder,? super android.graphics.ImageDecoder.ImageInfo,? super android.graphics.ImageDecoder.Source,kotlin.Unit> action);
-    method @RequiresApi(28) public static inline android.graphics.drawable.Drawable decodeDrawable(android.graphics.ImageDecoder.Source, kotlin.jvm.functions.Function3<? super android.graphics.ImageDecoder,? super android.graphics.ImageDecoder.ImageInfo,? super android.graphics.ImageDecoder.Source,kotlin.Unit> action);
-  }
-
-  public final class MatrixKt {
-    method public static android.graphics.Matrix rotationMatrix(float degrees, optional float px, optional float py);
-    method public static android.graphics.Matrix scaleMatrix(optional float sx, optional float sy);
-    method public static inline operator android.graphics.Matrix times(android.graphics.Matrix, android.graphics.Matrix m);
-    method public static android.graphics.Matrix translationMatrix(optional float tx, optional float ty);
-    method public static inline float[] values(android.graphics.Matrix);
-  }
-
-  public final class PaintKt {
-    method public static inline boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat? blendModeCompat);
-  }
-
-  public final class PathKt {
-    method @RequiresApi(19) public static inline infix android.graphics.Path and(android.graphics.Path, android.graphics.Path p);
-    method @RequiresApi(26) public static Iterable<androidx.core.graphics.PathSegment> flatten(android.graphics.Path, optional float error);
-    method @RequiresApi(19) public static inline operator android.graphics.Path minus(android.graphics.Path, android.graphics.Path p);
-    method @RequiresApi(19) public static inline infix android.graphics.Path or(android.graphics.Path, android.graphics.Path p);
-    method @RequiresApi(19) public static inline operator android.graphics.Path plus(android.graphics.Path, android.graphics.Path p);
-    method @RequiresApi(19) public static inline infix android.graphics.Path xor(android.graphics.Path, android.graphics.Path p);
-  }
-
-  public final class PictureKt {
-    method public static inline android.graphics.Picture record(android.graphics.Picture, int width, int height, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-  }
-
-  public final class PointKt {
-    method public static inline operator int component1(android.graphics.Point);
-    method public static inline operator float component1(android.graphics.PointF);
-    method public static inline operator int component2(android.graphics.Point);
-    method public static inline operator float component2(android.graphics.PointF);
-    method public static inline operator android.graphics.Point minus(android.graphics.Point, android.graphics.Point p);
-    method public static inline operator android.graphics.PointF minus(android.graphics.PointF, android.graphics.PointF p);
-    method public static inline operator android.graphics.Point minus(android.graphics.Point, int xy);
-    method public static inline operator android.graphics.PointF minus(android.graphics.PointF, float xy);
-    method public static inline operator android.graphics.Point plus(android.graphics.Point, android.graphics.Point p);
-    method public static inline operator android.graphics.PointF plus(android.graphics.PointF, android.graphics.PointF p);
-    method public static inline operator android.graphics.Point plus(android.graphics.Point, int xy);
-    method public static inline operator android.graphics.PointF plus(android.graphics.PointF, float xy);
-    method public static inline android.graphics.Point toPoint(android.graphics.PointF);
-    method public static inline android.graphics.PointF toPointF(android.graphics.Point);
-    method public static inline operator android.graphics.Point unaryMinus(android.graphics.Point);
-    method public static inline operator android.graphics.PointF unaryMinus(android.graphics.PointF);
-  }
-
-  public final class PorterDuffKt {
-    method public static inline android.graphics.PorterDuffColorFilter toColorFilter(android.graphics.PorterDuff.Mode, int color);
-    method public static inline android.graphics.PorterDuffXfermode toXfermode(android.graphics.PorterDuff.Mode);
-  }
-
-  public final class RectKt {
-    method public static inline infix android.graphics.Rect and(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline infix android.graphics.RectF and(android.graphics.RectF, android.graphics.RectF r);
-    method public static inline operator int component1(android.graphics.Rect);
-    method public static inline operator float component1(android.graphics.RectF);
-    method public static inline operator int component2(android.graphics.Rect);
-    method public static inline operator float component2(android.graphics.RectF);
-    method public static inline operator int component3(android.graphics.Rect);
-    method public static inline operator float component3(android.graphics.RectF);
-    method public static inline operator int component4(android.graphics.Rect);
-    method public static inline operator float component4(android.graphics.RectF);
-    method public static inline operator boolean contains(android.graphics.Rect, android.graphics.Point p);
-    method public static inline operator boolean contains(android.graphics.RectF, android.graphics.PointF p);
-    method public static inline operator android.graphics.Region minus(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline operator android.graphics.Region minus(android.graphics.RectF, android.graphics.RectF r);
-    method public static inline operator android.graphics.Rect minus(android.graphics.Rect, int xy);
-    method public static inline operator android.graphics.RectF minus(android.graphics.RectF, float xy);
-    method public static inline operator android.graphics.Rect minus(android.graphics.Rect, android.graphics.Point xy);
-    method public static inline operator android.graphics.RectF minus(android.graphics.RectF, android.graphics.PointF xy);
-    method public static inline infix android.graphics.Rect or(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline infix android.graphics.RectF or(android.graphics.RectF, android.graphics.RectF r);
-    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, android.graphics.RectF r);
-    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, int xy);
-    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, float xy);
-    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, android.graphics.Point xy);
-    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, android.graphics.PointF xy);
-    method public static inline operator android.graphics.Rect times(android.graphics.Rect, int factor);
-    method public static inline operator android.graphics.RectF times(android.graphics.RectF, int factor);
-    method public static inline operator android.graphics.RectF times(android.graphics.RectF, float factor);
-    method public static inline android.graphics.Rect toRect(android.graphics.RectF);
-    method public static inline android.graphics.RectF toRectF(android.graphics.Rect);
-    method public static inline android.graphics.Region toRegion(android.graphics.Rect);
-    method public static inline android.graphics.Region toRegion(android.graphics.RectF);
-    method public static inline android.graphics.RectF transform(android.graphics.RectF, android.graphics.Matrix m);
-    method public static inline infix android.graphics.Region xor(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline infix android.graphics.Region xor(android.graphics.RectF, android.graphics.RectF r);
-  }
-
-  public final class RegionKt {
-    method public static inline infix android.graphics.Region and(android.graphics.Region, android.graphics.Rect r);
-    method public static inline infix android.graphics.Region and(android.graphics.Region, android.graphics.Region r);
-    method public static inline operator boolean contains(android.graphics.Region, android.graphics.Point p);
-    method public static inline void forEach(android.graphics.Region, kotlin.jvm.functions.Function1<? super android.graphics.Rect,kotlin.Unit> action);
-    method public static operator java.util.Iterator<android.graphics.Rect> iterator(android.graphics.Region);
-    method public static inline operator android.graphics.Region minus(android.graphics.Region, android.graphics.Rect r);
-    method public static inline operator android.graphics.Region minus(android.graphics.Region, android.graphics.Region r);
-    method public static inline operator android.graphics.Region not(android.graphics.Region);
-    method public static inline infix android.graphics.Region or(android.graphics.Region, android.graphics.Rect r);
-    method public static inline infix android.graphics.Region or(android.graphics.Region, android.graphics.Region r);
-    method public static inline operator android.graphics.Region plus(android.graphics.Region, android.graphics.Rect r);
-    method public static inline operator android.graphics.Region plus(android.graphics.Region, android.graphics.Region r);
-    method public static inline operator android.graphics.Region unaryMinus(android.graphics.Region);
-    method public static inline infix android.graphics.Region xor(android.graphics.Region, android.graphics.Rect r);
-    method public static inline infix android.graphics.Region xor(android.graphics.Region, android.graphics.Region r);
-  }
-
-  public final class ShaderKt {
-    method public static inline void transform(android.graphics.Shader, kotlin.jvm.functions.Function1<? super android.graphics.Matrix,kotlin.Unit> block);
-  }
-
-}
-
-package androidx.core.graphics.drawable {
-
-  public final class BitmapDrawableKt {
-    method public static inline android.graphics.drawable.BitmapDrawable toDrawable(android.graphics.Bitmap, android.content.res.Resources resources);
-  }
-
-  public final class ColorDrawableKt {
-    method public static inline android.graphics.drawable.ColorDrawable toDrawable(@ColorInt int);
-    method @RequiresApi(26) public static inline android.graphics.drawable.ColorDrawable toDrawable(android.graphics.Color);
-  }
-
-  public final class DrawableKt {
-    method public static android.graphics.Bitmap toBitmap(android.graphics.drawable.Drawable, optional @Px int width, optional @Px int height, optional android.graphics.Bitmap.Config? config);
-    method public static android.graphics.Bitmap? toBitmapOrNull(android.graphics.drawable.Drawable, optional @Px int width, optional @Px int height, optional android.graphics.Bitmap.Config? config);
-    method public static void updateBounds(android.graphics.drawable.Drawable, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
-  }
-
-  public final class IconKt {
-    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toAdaptiveIcon(android.graphics.Bitmap);
-    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(android.graphics.Bitmap);
-    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(android.net.Uri);
-    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(byte[]);
-  }
-
-}
-
-package androidx.core.location {
-
-  public final class LocationKt {
-    method public static inline operator double component1(android.location.Location);
-    method public static inline operator double component2(android.location.Location);
-  }
-
-}
-
-package androidx.core.net {
-
-  public final class UriKt {
-    method public static java.io.File toFile(android.net.Uri);
-    method public static inline android.net.Uri toUri(String);
-    method public static inline android.net.Uri toUri(java.io.File);
-  }
-
-}
-
-package androidx.core.os {
-
-  public final class BundleKt {
-    method public static android.os.Bundle bundleOf(kotlin.Pair<java.lang.String,?>... pairs);
-    method public static android.os.Bundle bundleOf();
-  }
-
-  public final class HandlerKt {
-    method public static inline Runnable postAtTime(android.os.Handler, long uptimeMillis, optional Object? token, kotlin.jvm.functions.Function0<kotlin.Unit> action);
-    method public static inline Runnable postDelayed(android.os.Handler, long delayInMillis, optional Object? token, kotlin.jvm.functions.Function0<kotlin.Unit> action);
-  }
-
-  @RequiresApi(31) public final class OutcomeReceiverKt {
-    method @RequiresApi(31) public static <R, E extends java.lang.Throwable> android.os.OutcomeReceiver<R,E> asOutcomeReceiver(kotlin.coroutines.Continuation<? super R>);
-  }
-
-  public final class PersistableBundleKt {
-    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf(kotlin.Pair<java.lang.String,?>... pairs);
-    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf();
-    method @RequiresApi(21) public static android.os.PersistableBundle toPersistableBundle(java.util.Map<java.lang.String,?>);
-  }
-
-  public final class TraceKt {
-    method @Deprecated public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
-  }
-
-}
-
-package androidx.core.text {
-
-  public final class CharSequenceKt {
-    method public static inline boolean isDigitsOnly(CharSequence);
-    method public static inline int trimmedLength(CharSequence);
-  }
-
-  public final class HtmlKt {
-    method public static inline android.text.Spanned parseAsHtml(String, optional int flags, optional android.text.Html.ImageGetter? imageGetter, optional android.text.Html.TagHandler? tagHandler);
-    method public static inline String toHtml(android.text.Spanned, optional int option);
-  }
-
-  public final class LocaleKt {
-    method @RequiresApi(17) public static inline int getLayoutDirection(java.util.Locale);
-  }
-
-  public final class SpannableStringBuilderKt {
-    method public static inline android.text.SpannableStringBuilder backgroundColor(android.text.SpannableStringBuilder, @ColorInt int color, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder bold(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannedString buildSpannedString(kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder color(android.text.SpannableStringBuilder, @ColorInt int color, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder inSpans(android.text.SpannableStringBuilder, Object![] spans, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder inSpans(android.text.SpannableStringBuilder, Object span, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder italic(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder scale(android.text.SpannableStringBuilder, float proportion, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder strikeThrough(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder subscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder superscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder underline(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-  }
-
-  public final class SpannableStringKt {
-    method public static inline void clearSpans(android.text.Spannable);
-    method public static inline operator void set(android.text.Spannable, int start, int end, Object span);
-    method public static inline operator void set(android.text.Spannable, kotlin.ranges.IntRange range, Object span);
-    method public static inline android.text.Spannable toSpannable(CharSequence);
-  }
-
-  public final class SpannedStringKt {
-    method public static inline <reified T> T![]! getSpans(android.text.Spanned, optional int start, optional int end);
-    method public static inline android.text.Spanned toSpanned(CharSequence);
-  }
-
-  public final class StringKt {
-    method public static inline String htmlEncode(String);
-  }
-
-}
-
-package androidx.core.transition {
-
-  public final class TransitionKt {
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener addListener(android.transition.Transition, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onEnd, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onStart, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onCancel, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onResume, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onPause);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnCancel(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnEnd(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnPause(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnResume(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnStart(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-  }
-
-}
-
-package androidx.core.util {
-
-  public final class AndroidXConsumerKt {
-    method public static <T> androidx.core.util.Consumer<T> asAndroidXConsumer(kotlin.coroutines.Continuation<? super T>);
-  }
-
-  public final class AtomicFileKt {
-    method @RequiresApi(17) public static inline byte[] readBytes(android.util.AtomicFile);
-    method @RequiresApi(17) public static String readText(android.util.AtomicFile, optional java.nio.charset.Charset charset);
-    method @RequiresApi(17) public static inline void tryWrite(android.util.AtomicFile, kotlin.jvm.functions.Function1<? super java.io.FileOutputStream,kotlin.Unit> block);
-    method @RequiresApi(17) public static void writeBytes(android.util.AtomicFile, byte[] array);
-    method @RequiresApi(17) public static void writeText(android.util.AtomicFile, String text, optional java.nio.charset.Charset charset);
-  }
-
-  @RequiresApi(24) public final class ConsumerKt {
-    method @RequiresApi(24) public static <T> java.util.function.Consumer<T> asConsumer(kotlin.coroutines.Continuation<? super T>);
-  }
-
-  public final class HalfKt {
-    method @RequiresApi(26) public static inline android.util.Half toHalf(@HalfFloat short);
-    method @RequiresApi(26) public static inline android.util.Half toHalf(float);
-    method @RequiresApi(26) public static inline android.util.Half toHalf(double);
-    method @RequiresApi(26) public static inline android.util.Half toHalf(String);
-  }
-
-  public final class LongSparseArrayKt {
-    method @RequiresApi(16) public static inline operator <T> boolean contains(android.util.LongSparseArray<T>, long key);
-    method @RequiresApi(16) public static inline <T> boolean containsKey(android.util.LongSparseArray<T>, long key);
-    method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T? value);
-    method @RequiresApi(16) public static inline <T> void forEach(android.util.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
-    method @RequiresApi(16) public static inline <T> T! getOrDefault(android.util.LongSparseArray<T>, long key, T? defaultValue);
-    method @RequiresApi(16) public static inline <T> T! getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
-    method @RequiresApi(16) public static inline <T> int getSize(android.util.LongSparseArray<T>);
-    method @RequiresApi(16) public static inline <T> boolean isEmpty(android.util.LongSparseArray<T>);
-    method @RequiresApi(16) public static inline <T> boolean isNotEmpty(android.util.LongSparseArray<T>);
-    method @RequiresApi(16) public static <T> kotlin.collections.LongIterator keyIterator(android.util.LongSparseArray<T>);
-    method @RequiresApi(16) public static operator <T> android.util.LongSparseArray<T> plus(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
-    method @RequiresApi(16) public static <T> void putAll(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
-    method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T? value);
-    method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T? value);
-    method @RequiresApi(16) public static <T> java.util.Iterator<T> valueIterator(android.util.LongSparseArray<T>);
-  }
-
-  public final class LruCacheKt {
-    method public static inline <K, V> android.util.LruCache<K,V> lruCache(int maxSize, optional kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Integer> sizeOf, optional kotlin.jvm.functions.Function1<? super K,? extends V> create, optional kotlin.jvm.functions.Function4<? super java.lang.Boolean,? super K,? super V,? super V,kotlin.Unit> onEntryRemoved);
-  }
-
-  public final class PairKt {
-    method public static inline operator <F, S> F! component1(androidx.core.util.Pair<F,S>);
-    method public static inline operator <F, S> F! component1(android.util.Pair<F,S>);
-    method public static inline operator <F, S> S! component2(androidx.core.util.Pair<F,S>);
-    method public static inline operator <F, S> S! component2(android.util.Pair<F,S>);
-    method public static inline <F, S> android.util.Pair<F,S> toAndroidPair(kotlin.Pair<? extends F,? extends S>);
-    method public static inline <F, S> androidx.core.util.Pair<F,S> toAndroidXPair(kotlin.Pair<? extends F,? extends S>);
-    method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(androidx.core.util.Pair<F,S>);
-    method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(android.util.Pair<F,S>);
-  }
-
-  public final class RangeKt {
-    method @RequiresApi(21) public static inline infix <T extends java.lang.Comparable<? super T>> android.util.Range<T> and(android.util.Range<T>, android.util.Range<T> other);
-    method @RequiresApi(21) public static inline operator <T extends java.lang.Comparable<? super T>> android.util.Range<T> plus(android.util.Range<T>, T value);
-    method @RequiresApi(21) public static inline operator <T extends java.lang.Comparable<? super T>> android.util.Range<T> plus(android.util.Range<T>, android.util.Range<T> other);
-    method @RequiresApi(21) public static inline infix <T extends java.lang.Comparable<? super T>> android.util.Range<T> rangeTo(T, T that);
-    method @RequiresApi(21) public static <T extends java.lang.Comparable<? super T>> kotlin.ranges.ClosedRange<T> toClosedRange(android.util.Range<T>);
-    method @RequiresApi(21) public static <T extends java.lang.Comparable<? super T>> android.util.Range<T> toRange(kotlin.ranges.ClosedRange<T>);
-  }
-
-  public final class RunnableKt {
-    method public static Runnable asRunnable(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-  }
-
-  public final class SizeKt {
-    method @RequiresApi(21) public static inline operator int component1(android.util.Size);
-    method @RequiresApi(21) public static inline operator float component1(android.util.SizeF);
-    method public static inline operator float component1(androidx.core.util.SizeFCompat);
-    method @RequiresApi(21) public static inline operator int component2(android.util.Size);
-    method @RequiresApi(21) public static inline operator float component2(android.util.SizeF);
-    method public static inline operator float component2(androidx.core.util.SizeFCompat);
-  }
-
-  public final class SparseArrayKt {
-    method public static inline operator <T> boolean contains(android.util.SparseArray<T>, int key);
-    method public static inline <T> boolean containsKey(android.util.SparseArray<T>, int key);
-    method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T? value);
-    method public static inline <T> void forEach(android.util.SparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
-    method public static inline <T> T! getOrDefault(android.util.SparseArray<T>, int key, T? defaultValue);
-    method public static inline <T> T! getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
-    method public static inline <T> int getSize(android.util.SparseArray<T>);
-    method public static inline <T> boolean isEmpty(android.util.SparseArray<T>);
-    method public static inline <T> boolean isNotEmpty(android.util.SparseArray<T>);
-    method public static <T> kotlin.collections.IntIterator keyIterator(android.util.SparseArray<T>);
-    method public static operator <T> android.util.SparseArray<T> plus(android.util.SparseArray<T>, android.util.SparseArray<T> other);
-    method public static <T> void putAll(android.util.SparseArray<T>, android.util.SparseArray<T> other);
-    method public static <T> boolean remove(android.util.SparseArray<T>, int key, T? value);
-    method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T? value);
-    method public static <T> java.util.Iterator<T> valueIterator(android.util.SparseArray<T>);
-  }
-
-  public final class SparseBooleanArrayKt {
-    method public static inline operator boolean contains(android.util.SparseBooleanArray, int key);
-    method public static inline boolean containsKey(android.util.SparseBooleanArray, int key);
-    method public static inline boolean containsValue(android.util.SparseBooleanArray, boolean value);
-    method public static inline void forEach(android.util.SparseBooleanArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Boolean,kotlin.Unit> action);
-    method public static inline boolean getOrDefault(android.util.SparseBooleanArray, int key, boolean defaultValue);
-    method public static inline boolean getOrElse(android.util.SparseBooleanArray, int key, kotlin.jvm.functions.Function0<java.lang.Boolean> defaultValue);
-    method public static inline int getSize(android.util.SparseBooleanArray);
-    method public static inline boolean isEmpty(android.util.SparseBooleanArray);
-    method public static inline boolean isNotEmpty(android.util.SparseBooleanArray);
-    method public static kotlin.collections.IntIterator keyIterator(android.util.SparseBooleanArray);
-    method public static operator android.util.SparseBooleanArray plus(android.util.SparseBooleanArray, android.util.SparseBooleanArray other);
-    method public static void putAll(android.util.SparseBooleanArray, android.util.SparseBooleanArray other);
-    method public static boolean remove(android.util.SparseBooleanArray, int key, boolean value);
-    method public static inline operator void set(android.util.SparseBooleanArray, int key, boolean value);
-    method public static kotlin.collections.BooleanIterator valueIterator(android.util.SparseBooleanArray);
-  }
-
-  public final class SparseIntArrayKt {
-    method public static inline operator boolean contains(android.util.SparseIntArray, int key);
-    method public static inline boolean containsKey(android.util.SparseIntArray, int key);
-    method public static inline boolean containsValue(android.util.SparseIntArray, int value);
-    method public static inline void forEach(android.util.SparseIntArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
-    method public static inline int getOrDefault(android.util.SparseIntArray, int key, int defaultValue);
-    method public static inline int getOrElse(android.util.SparseIntArray, int key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
-    method public static inline int getSize(android.util.SparseIntArray);
-    method public static inline boolean isEmpty(android.util.SparseIntArray);
-    method public static inline boolean isNotEmpty(android.util.SparseIntArray);
-    method public static kotlin.collections.IntIterator keyIterator(android.util.SparseIntArray);
-    method public static operator android.util.SparseIntArray plus(android.util.SparseIntArray, android.util.SparseIntArray other);
-    method public static void putAll(android.util.SparseIntArray, android.util.SparseIntArray other);
-    method public static boolean remove(android.util.SparseIntArray, int key, int value);
-    method public static inline operator void set(android.util.SparseIntArray, int key, int value);
-    method public static kotlin.collections.IntIterator valueIterator(android.util.SparseIntArray);
-  }
-
-  public final class SparseLongArrayKt {
-    method @RequiresApi(18) public static inline operator boolean contains(android.util.SparseLongArray, int key);
-    method @RequiresApi(18) public static inline boolean containsKey(android.util.SparseLongArray, int key);
-    method @RequiresApi(18) public static inline boolean containsValue(android.util.SparseLongArray, long value);
-    method @RequiresApi(18) public static inline void forEach(android.util.SparseLongArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,kotlin.Unit> action);
-    method @RequiresApi(18) public static inline long getOrDefault(android.util.SparseLongArray, int key, long defaultValue);
-    method @RequiresApi(18) public static inline long getOrElse(android.util.SparseLongArray, int key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
-    method @RequiresApi(18) public static inline int getSize(android.util.SparseLongArray);
-    method @RequiresApi(18) public static inline boolean isEmpty(android.util.SparseLongArray);
-    method @RequiresApi(18) public static inline boolean isNotEmpty(android.util.SparseLongArray);
-    method @RequiresApi(18) public static kotlin.collections.IntIterator keyIterator(android.util.SparseLongArray);
-    method @RequiresApi(18) public static operator android.util.SparseLongArray plus(android.util.SparseLongArray, android.util.SparseLongArray other);
-    method @RequiresApi(18) public static void putAll(android.util.SparseLongArray, android.util.SparseLongArray other);
-    method @RequiresApi(18) public static boolean remove(android.util.SparseLongArray, int key, long value);
-    method @RequiresApi(18) public static inline operator void set(android.util.SparseLongArray, int key, long value);
-    method @RequiresApi(18) public static kotlin.collections.LongIterator valueIterator(android.util.SparseLongArray);
-  }
-
-}
-
-package androidx.core.view {
-
-  public final class MenuKt {
-    method public static operator boolean contains(android.view.Menu, android.view.MenuItem item);
-    method public static inline void forEach(android.view.Menu, kotlin.jvm.functions.Function1<? super android.view.MenuItem,kotlin.Unit> action);
-    method public static inline void forEachIndexed(android.view.Menu, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.view.MenuItem,kotlin.Unit> action);
-    method public static inline operator android.view.MenuItem get(android.view.Menu, int index);
-    method public static kotlin.sequences.Sequence<android.view.MenuItem> getChildren(android.view.Menu);
-    method public static inline int getSize(android.view.Menu);
-    method public static inline boolean isEmpty(android.view.Menu);
-    method public static inline boolean isNotEmpty(android.view.Menu);
-    method public static operator java.util.Iterator<android.view.MenuItem> iterator(android.view.Menu);
-    method public static inline operator void minusAssign(android.view.Menu, android.view.MenuItem item);
-  }
-
-  public final class ViewGroupKt {
-    method public static inline operator boolean contains(android.view.ViewGroup, android.view.View view);
-    method public static inline void forEach(android.view.ViewGroup, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline void forEachIndexed(android.view.ViewGroup, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.view.View,kotlin.Unit> action);
-    method public static operator android.view.View get(android.view.ViewGroup, int index);
-    method public static kotlin.sequences.Sequence<android.view.View> getChildren(android.view.ViewGroup);
-    method public static kotlin.sequences.Sequence<android.view.View> getDescendants(android.view.ViewGroup);
-    method public static inline kotlin.ranges.IntRange getIndices(android.view.ViewGroup);
-    method public static inline int getSize(android.view.ViewGroup);
-    method public static inline boolean isEmpty(android.view.ViewGroup);
-    method public static inline boolean isNotEmpty(android.view.ViewGroup);
-    method public static operator java.util.Iterator<android.view.View> iterator(android.view.ViewGroup);
-    method public static inline operator void minusAssign(android.view.ViewGroup, android.view.View view);
-    method public static inline operator void plusAssign(android.view.ViewGroup, android.view.View view);
-    method public static inline void setMargins(android.view.ViewGroup.MarginLayoutParams, @Px int size);
-    method public static inline void updateMargins(android.view.ViewGroup.MarginLayoutParams, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
-    method @RequiresApi(17) public static inline void updateMarginsRelative(android.view.ViewGroup.MarginLayoutParams, optional @Px int start, optional @Px int top, optional @Px int end, optional @Px int bottom);
-  }
-
-  public final class ViewKt {
-    method public static inline void doOnAttach(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline void doOnDetach(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline void doOnLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline void doOnNextLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline androidx.core.view.OneShotPreDrawListener doOnPreDraw(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static android.graphics.Bitmap drawToBitmap(android.view.View, optional android.graphics.Bitmap.Config config);
-    method public static kotlin.sequences.Sequence<android.view.View> getAllViews(android.view.View);
-    method public static kotlin.sequences.Sequence<android.view.ViewParent> getAncestors(android.view.View);
-    method public static inline int getMarginBottom(android.view.View);
-    method public static inline int getMarginEnd(android.view.View);
-    method public static inline int getMarginLeft(android.view.View);
-    method public static inline int getMarginRight(android.view.View);
-    method public static inline int getMarginStart(android.view.View);
-    method public static inline int getMarginTop(android.view.View);
-    method public static inline boolean isGone(android.view.View);
-    method public static inline boolean isInvisible(android.view.View);
-    method public static inline boolean isVisible(android.view.View);
-    method public static inline Runnable postDelayed(android.view.View, long delayInMillis, kotlin.jvm.functions.Function0<kotlin.Unit> action);
-    method @RequiresApi(16) public static inline Runnable postOnAnimationDelayed(android.view.View, long delayInMillis, kotlin.jvm.functions.Function0<kotlin.Unit> action);
-    method public static inline void setGone(android.view.View, boolean);
-    method public static inline void setInvisible(android.view.View, boolean);
-    method public static inline void setPadding(android.view.View, @Px int size);
-    method public static inline void setVisible(android.view.View, boolean);
-    method public static inline void updateLayoutParams(android.view.View, kotlin.jvm.functions.Function1<? super android.view.ViewGroup.LayoutParams,kotlin.Unit> block);
-    method public static inline <reified T extends android.view.ViewGroup.LayoutParams> void updateLayoutParams(android.view.View, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> block);
-    method public static inline void updatePadding(android.view.View, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
-    method @RequiresApi(17) public static inline void updatePaddingRelative(android.view.View, optional @Px int start, optional @Px int top, optional @Px int end, optional @Px int bottom);
-  }
-
-}
-
-package androidx.core.widget {
-
-  public final class TextViewKt {
-    method public static inline android.text.TextWatcher addTextChangedListener(android.widget.TextView, optional kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> beforeTextChanged, optional kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> onTextChanged, optional kotlin.jvm.functions.Function1<? super android.text.Editable,kotlin.Unit> afterTextChanged);
-    method public static inline android.text.TextWatcher doAfterTextChanged(android.widget.TextView, kotlin.jvm.functions.Function1<? super android.text.Editable,kotlin.Unit> action);
-    method public static inline android.text.TextWatcher doBeforeTextChanged(android.widget.TextView, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
-    method public static inline android.text.TextWatcher doOnTextChanged(android.widget.TextView, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
-  }
-
-}
-
diff --git a/core/core-ktx/api/restricted_1.8.0-beta01.txt b/core/core-ktx/api/restricted_1.8.0-beta01.txt
deleted file mode 100644
index 521f26c..0000000
--- a/core/core-ktx/api/restricted_1.8.0-beta01.txt
+++ /dev/null
@@ -1,629 +0,0 @@
-// Signature format: 4.0
-package androidx.core.animation {
-
-  public final class AnimatorKt {
-    method public static inline android.animation.Animator.AnimatorListener addListener(android.animation.Animator, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onEnd, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onStart, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onCancel, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onRepeat);
-    method @RequiresApi(19) public static inline android.animation.Animator.AnimatorPauseListener addPauseListener(android.animation.Animator, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onResume, optional kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> onPause);
-    method public static inline android.animation.Animator.AnimatorListener doOnCancel(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method public static inline android.animation.Animator.AnimatorListener doOnEnd(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.animation.Animator.AnimatorPauseListener doOnPause(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method public static inline android.animation.Animator.AnimatorListener doOnRepeat(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.animation.Animator.AnimatorPauseListener doOnResume(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-    method public static inline android.animation.Animator.AnimatorListener doOnStart(android.animation.Animator, kotlin.jvm.functions.Function1<? super android.animation.Animator,kotlin.Unit> action);
-  }
-
-}
-
-package androidx.core.content {
-
-  public final class ContentValuesKt {
-    method public static android.content.ContentValues contentValuesOf(kotlin.Pair<java.lang.String,?>... pairs);
-  }
-
-  public final class ContextKt {
-    method public static inline <reified T> T! getSystemService(android.content.Context);
-    method public static inline void withStyledAttributes(android.content.Context, optional android.util.AttributeSet? set, int[] attrs, optional @AttrRes int defStyleAttr, optional @StyleRes int defStyleRes, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
-    method public static inline void withStyledAttributes(android.content.Context, @StyleRes int resourceId, int[] attrs, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
-  }
-
-  public final class SharedPreferencesKt {
-    method public static inline void edit(android.content.SharedPreferences, optional boolean commit, kotlin.jvm.functions.Function1<? super android.content.SharedPreferences.Editor,kotlin.Unit> action);
-  }
-
-}
-
-package androidx.core.content.res {
-
-  public final class TypedArrayKt {
-    method public static boolean getBooleanOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @ColorInt public static int getColorOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static android.content.res.ColorStateList getColorStateListOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static float getDimensionOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @Dimension public static int getDimensionPixelOffsetOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @Dimension public static int getDimensionPixelSizeOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static android.graphics.drawable.Drawable getDrawableOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static float getFloatOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @RequiresApi(26) public static android.graphics.Typeface getFontOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static int getIntOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static int getIntegerOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method @AnyRes public static int getResourceIdOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static String getStringOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static CharSequence![] getTextArrayOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static CharSequence getTextOrThrow(android.content.res.TypedArray, @StyleableRes int index);
-    method public static inline <R> R! use(android.content.res.TypedArray, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,? extends R> block);
-  }
-
-}
-
-package androidx.core.database {
-
-  public final class CursorKt {
-    method public static inline byte[]? getBlobOrNull(android.database.Cursor, int index);
-    method public static inline Double? getDoubleOrNull(android.database.Cursor, int index);
-    method public static inline Float? getFloatOrNull(android.database.Cursor, int index);
-    method public static inline Integer? getIntOrNull(android.database.Cursor, int index);
-    method public static inline Long? getLongOrNull(android.database.Cursor, int index);
-    method public static inline Short? getShortOrNull(android.database.Cursor, int index);
-    method public static inline String? getStringOrNull(android.database.Cursor, int index);
-  }
-
-}
-
-package androidx.core.database.sqlite {
-
-  public final class SQLiteDatabaseKt {
-    method public static inline <T> T! transaction(android.database.sqlite.SQLiteDatabase, optional boolean exclusive, kotlin.jvm.functions.Function1<? super android.database.sqlite.SQLiteDatabase,? extends T> body);
-  }
-
-}
-
-package androidx.core.graphics {
-
-  public final class BitmapKt {
-    method public static inline android.graphics.Bitmap applyCanvas(android.graphics.Bitmap, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline operator boolean contains(android.graphics.Bitmap, android.graphics.Point p);
-    method public static inline operator boolean contains(android.graphics.Bitmap, android.graphics.PointF p);
-    method public static inline android.graphics.Bitmap createBitmap(int width, int height, optional android.graphics.Bitmap.Config config);
-    method @RequiresApi(26) public static inline android.graphics.Bitmap createBitmap(int width, int height, optional android.graphics.Bitmap.Config config, optional boolean hasAlpha, optional android.graphics.ColorSpace colorSpace);
-    method public static inline operator int get(android.graphics.Bitmap, int x, int y);
-    method public static inline android.graphics.Bitmap scale(android.graphics.Bitmap, int width, int height, optional boolean filter);
-    method public static inline operator void set(android.graphics.Bitmap, int x, int y, @ColorInt int color);
-  }
-
-  public final class CanvasKt {
-    method public static inline void withClip(android.graphics.Canvas, android.graphics.Rect clipRect, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withClip(android.graphics.Canvas, android.graphics.RectF clipRect, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withClip(android.graphics.Canvas, int left, int top, int right, int bottom, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withClip(android.graphics.Canvas, float left, float top, float right, float bottom, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withClip(android.graphics.Canvas, android.graphics.Path clipPath, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withMatrix(android.graphics.Canvas, optional android.graphics.Matrix matrix, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withRotation(android.graphics.Canvas, optional float degrees, optional float pivotX, optional float pivotY, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withSave(android.graphics.Canvas, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withScale(android.graphics.Canvas, optional float x, optional float y, optional float pivotX, optional float pivotY, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withSkew(android.graphics.Canvas, optional float x, optional float y, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-    method public static inline void withTranslation(android.graphics.Canvas, optional float x, optional float y, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-  }
-
-  public final class ColorKt {
-    method @RequiresApi(26) public static inline operator float component1(android.graphics.Color);
-    method public static inline operator int component1(@ColorInt int);
-    method @RequiresApi(26) public static inline operator float component1(@ColorLong long);
-    method @RequiresApi(26) public static inline operator float component2(android.graphics.Color);
-    method public static inline operator int component2(@ColorInt int);
-    method @RequiresApi(26) public static inline operator float component2(@ColorLong long);
-    method @RequiresApi(26) public static inline operator float component3(android.graphics.Color);
-    method public static inline operator int component3(@ColorInt int);
-    method @RequiresApi(26) public static inline operator float component3(@ColorLong long);
-    method @RequiresApi(26) public static inline operator float component4(android.graphics.Color);
-    method public static inline operator int component4(@ColorInt int);
-    method @RequiresApi(26) public static inline operator float component4(@ColorLong long);
-    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorInt int, android.graphics.ColorSpace.Named colorSpace);
-    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorInt int, android.graphics.ColorSpace colorSpace);
-    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorLong long, android.graphics.ColorSpace.Named colorSpace);
-    method @ColorLong @RequiresApi(26) public static inline infix long convertTo(@ColorLong long, android.graphics.ColorSpace colorSpace);
-    method @RequiresApi(26) public static inline infix android.graphics.Color convertTo(android.graphics.Color, android.graphics.ColorSpace.Named colorSpace);
-    method @RequiresApi(26) public static inline infix android.graphics.Color convertTo(android.graphics.Color, android.graphics.ColorSpace colorSpace);
-    method public static inline int getAlpha(@ColorInt int);
-    method @RequiresApi(26) public static inline float getAlpha(@ColorLong long);
-    method public static inline int getBlue(@ColorInt int);
-    method @RequiresApi(26) public static inline float getBlue(@ColorLong long);
-    method @RequiresApi(26) public static inline android.graphics.ColorSpace getColorSpace(@ColorLong long);
-    method public static inline int getGreen(@ColorInt int);
-    method @RequiresApi(26) public static inline float getGreen(@ColorLong long);
-    method @RequiresApi(26) public static inline float getLuminance(@ColorInt int);
-    method @RequiresApi(26) public static inline float getLuminance(@ColorLong long);
-    method public static inline int getRed(@ColorInt int);
-    method @RequiresApi(26) public static inline float getRed(@ColorLong long);
-    method @RequiresApi(26) public static inline boolean isSrgb(@ColorLong long);
-    method @RequiresApi(26) public static inline boolean isWideGamut(@ColorLong long);
-    method @RequiresApi(26) public static operator android.graphics.Color plus(android.graphics.Color, android.graphics.Color c);
-    method @RequiresApi(26) public static inline android.graphics.Color toColor(@ColorInt int);
-    method @RequiresApi(26) public static inline android.graphics.Color toColor(@ColorLong long);
-    method @ColorInt @RequiresApi(26) public static inline int toColorInt(@ColorLong long);
-    method @ColorInt public static inline int toColorInt(String);
-    method @ColorLong @RequiresApi(26) public static inline long toColorLong(@ColorInt int);
-  }
-
-  public final class ImageDecoderKt {
-    method @RequiresApi(28) public static inline android.graphics.Bitmap decodeBitmap(android.graphics.ImageDecoder.Source, kotlin.jvm.functions.Function3<? super android.graphics.ImageDecoder,? super android.graphics.ImageDecoder.ImageInfo,? super android.graphics.ImageDecoder.Source,kotlin.Unit> action);
-    method @RequiresApi(28) public static inline android.graphics.drawable.Drawable decodeDrawable(android.graphics.ImageDecoder.Source, kotlin.jvm.functions.Function3<? super android.graphics.ImageDecoder,? super android.graphics.ImageDecoder.ImageInfo,? super android.graphics.ImageDecoder.Source,kotlin.Unit> action);
-  }
-
-  public final class MatrixKt {
-    method public static android.graphics.Matrix rotationMatrix(float degrees, optional float px, optional float py);
-    method public static android.graphics.Matrix scaleMatrix(optional float sx, optional float sy);
-    method public static inline operator android.graphics.Matrix times(android.graphics.Matrix, android.graphics.Matrix m);
-    method public static android.graphics.Matrix translationMatrix(optional float tx, optional float ty);
-    method public static inline float[] values(android.graphics.Matrix);
-  }
-
-  public final class PaintKt {
-    method public static inline boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat? blendModeCompat);
-  }
-
-  public final class PathKt {
-    method @RequiresApi(19) public static inline infix android.graphics.Path and(android.graphics.Path, android.graphics.Path p);
-    method @RequiresApi(26) public static Iterable<androidx.core.graphics.PathSegment> flatten(android.graphics.Path, optional float error);
-    method @RequiresApi(19) public static inline operator android.graphics.Path minus(android.graphics.Path, android.graphics.Path p);
-    method @RequiresApi(19) public static inline infix android.graphics.Path or(android.graphics.Path, android.graphics.Path p);
-    method @RequiresApi(19) public static inline operator android.graphics.Path plus(android.graphics.Path, android.graphics.Path p);
-    method @RequiresApi(19) public static inline infix android.graphics.Path xor(android.graphics.Path, android.graphics.Path p);
-  }
-
-  public final class PictureKt {
-    method public static inline android.graphics.Picture record(android.graphics.Picture, int width, int height, kotlin.jvm.functions.Function1<? super android.graphics.Canvas,kotlin.Unit> block);
-  }
-
-  public final class PointKt {
-    method public static inline operator int component1(android.graphics.Point);
-    method public static inline operator float component1(android.graphics.PointF);
-    method public static inline operator int component2(android.graphics.Point);
-    method public static inline operator float component2(android.graphics.PointF);
-    method public static inline operator android.graphics.Point minus(android.graphics.Point, android.graphics.Point p);
-    method public static inline operator android.graphics.PointF minus(android.graphics.PointF, android.graphics.PointF p);
-    method public static inline operator android.graphics.Point minus(android.graphics.Point, int xy);
-    method public static inline operator android.graphics.PointF minus(android.graphics.PointF, float xy);
-    method public static inline operator android.graphics.Point plus(android.graphics.Point, android.graphics.Point p);
-    method public static inline operator android.graphics.PointF plus(android.graphics.PointF, android.graphics.PointF p);
-    method public static inline operator android.graphics.Point plus(android.graphics.Point, int xy);
-    method public static inline operator android.graphics.PointF plus(android.graphics.PointF, float xy);
-    method public static inline android.graphics.Point toPoint(android.graphics.PointF);
-    method public static inline android.graphics.PointF toPointF(android.graphics.Point);
-    method public static inline operator android.graphics.Point unaryMinus(android.graphics.Point);
-    method public static inline operator android.graphics.PointF unaryMinus(android.graphics.PointF);
-  }
-
-  public final class PorterDuffKt {
-    method public static inline android.graphics.PorterDuffColorFilter toColorFilter(android.graphics.PorterDuff.Mode, int color);
-    method public static inline android.graphics.PorterDuffXfermode toXfermode(android.graphics.PorterDuff.Mode);
-  }
-
-  public final class RectKt {
-    method public static inline infix android.graphics.Rect and(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline infix android.graphics.RectF and(android.graphics.RectF, android.graphics.RectF r);
-    method public static inline operator int component1(android.graphics.Rect);
-    method public static inline operator float component1(android.graphics.RectF);
-    method public static inline operator int component2(android.graphics.Rect);
-    method public static inline operator float component2(android.graphics.RectF);
-    method public static inline operator int component3(android.graphics.Rect);
-    method public static inline operator float component3(android.graphics.RectF);
-    method public static inline operator int component4(android.graphics.Rect);
-    method public static inline operator float component4(android.graphics.RectF);
-    method public static inline operator boolean contains(android.graphics.Rect, android.graphics.Point p);
-    method public static inline operator boolean contains(android.graphics.RectF, android.graphics.PointF p);
-    method public static inline operator android.graphics.Region minus(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline operator android.graphics.Region minus(android.graphics.RectF, android.graphics.RectF r);
-    method public static inline operator android.graphics.Rect minus(android.graphics.Rect, int xy);
-    method public static inline operator android.graphics.RectF minus(android.graphics.RectF, float xy);
-    method public static inline operator android.graphics.Rect minus(android.graphics.Rect, android.graphics.Point xy);
-    method public static inline operator android.graphics.RectF minus(android.graphics.RectF, android.graphics.PointF xy);
-    method public static inline infix android.graphics.Rect or(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline infix android.graphics.RectF or(android.graphics.RectF, android.graphics.RectF r);
-    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, android.graphics.RectF r);
-    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, int xy);
-    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, float xy);
-    method public static inline operator android.graphics.Rect plus(android.graphics.Rect, android.graphics.Point xy);
-    method public static inline operator android.graphics.RectF plus(android.graphics.RectF, android.graphics.PointF xy);
-    method public static inline operator android.graphics.Rect times(android.graphics.Rect, int factor);
-    method public static inline operator android.graphics.RectF times(android.graphics.RectF, int factor);
-    method public static inline operator android.graphics.RectF times(android.graphics.RectF, float factor);
-    method public static inline android.graphics.Rect toRect(android.graphics.RectF);
-    method public static inline android.graphics.RectF toRectF(android.graphics.Rect);
-    method public static inline android.graphics.Region toRegion(android.graphics.Rect);
-    method public static inline android.graphics.Region toRegion(android.graphics.RectF);
-    method public static inline android.graphics.RectF transform(android.graphics.RectF, android.graphics.Matrix m);
-    method public static inline infix android.graphics.Region xor(android.graphics.Rect, android.graphics.Rect r);
-    method public static inline infix android.graphics.Region xor(android.graphics.RectF, android.graphics.RectF r);
-  }
-
-  public final class RegionKt {
-    method public static inline infix android.graphics.Region and(android.graphics.Region, android.graphics.Rect r);
-    method public static inline infix android.graphics.Region and(android.graphics.Region, android.graphics.Region r);
-    method public static inline operator boolean contains(android.graphics.Region, android.graphics.Point p);
-    method public static inline void forEach(android.graphics.Region, kotlin.jvm.functions.Function1<? super android.graphics.Rect,kotlin.Unit> action);
-    method public static operator java.util.Iterator<android.graphics.Rect> iterator(android.graphics.Region);
-    method public static inline operator android.graphics.Region minus(android.graphics.Region, android.graphics.Rect r);
-    method public static inline operator android.graphics.Region minus(android.graphics.Region, android.graphics.Region r);
-    method public static inline operator android.graphics.Region not(android.graphics.Region);
-    method public static inline infix android.graphics.Region or(android.graphics.Region, android.graphics.Rect r);
-    method public static inline infix android.graphics.Region or(android.graphics.Region, android.graphics.Region r);
-    method public static inline operator android.graphics.Region plus(android.graphics.Region, android.graphics.Rect r);
-    method public static inline operator android.graphics.Region plus(android.graphics.Region, android.graphics.Region r);
-    method public static inline operator android.graphics.Region unaryMinus(android.graphics.Region);
-    method public static inline infix android.graphics.Region xor(android.graphics.Region, android.graphics.Rect r);
-    method public static inline infix android.graphics.Region xor(android.graphics.Region, android.graphics.Region r);
-  }
-
-  public final class ShaderKt {
-    method public static inline void transform(android.graphics.Shader, kotlin.jvm.functions.Function1<? super android.graphics.Matrix,kotlin.Unit> block);
-  }
-
-}
-
-package androidx.core.graphics.drawable {
-
-  public final class BitmapDrawableKt {
-    method public static inline android.graphics.drawable.BitmapDrawable toDrawable(android.graphics.Bitmap, android.content.res.Resources resources);
-  }
-
-  public final class ColorDrawableKt {
-    method public static inline android.graphics.drawable.ColorDrawable toDrawable(@ColorInt int);
-    method @RequiresApi(26) public static inline android.graphics.drawable.ColorDrawable toDrawable(android.graphics.Color);
-  }
-
-  public final class DrawableKt {
-    method public static android.graphics.Bitmap toBitmap(android.graphics.drawable.Drawable, optional @Px int width, optional @Px int height, optional android.graphics.Bitmap.Config? config);
-    method public static android.graphics.Bitmap? toBitmapOrNull(android.graphics.drawable.Drawable, optional @Px int width, optional @Px int height, optional android.graphics.Bitmap.Config? config);
-    method public static void updateBounds(android.graphics.drawable.Drawable, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
-  }
-
-  public final class IconKt {
-    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toAdaptiveIcon(android.graphics.Bitmap);
-    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(android.graphics.Bitmap);
-    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(android.net.Uri);
-    method @RequiresApi(26) public static inline android.graphics.drawable.Icon toIcon(byte[]);
-  }
-
-}
-
-package androidx.core.location {
-
-  public final class LocationKt {
-    method public static inline operator double component1(android.location.Location);
-    method public static inline operator double component2(android.location.Location);
-  }
-
-}
-
-package androidx.core.net {
-
-  public final class UriKt {
-    method public static java.io.File toFile(android.net.Uri);
-    method public static inline android.net.Uri toUri(String);
-    method public static inline android.net.Uri toUri(java.io.File);
-  }
-
-}
-
-package androidx.core.os {
-
-  public final class BundleKt {
-    method public static android.os.Bundle bundleOf(kotlin.Pair<java.lang.String,?>... pairs);
-    method public static android.os.Bundle bundleOf();
-  }
-
-  public final class HandlerKt {
-    method public static inline Runnable postAtTime(android.os.Handler, long uptimeMillis, optional Object? token, kotlin.jvm.functions.Function0<kotlin.Unit> action);
-    method public static inline Runnable postDelayed(android.os.Handler, long delayInMillis, optional Object? token, kotlin.jvm.functions.Function0<kotlin.Unit> action);
-  }
-
-  @RequiresApi(31) public final class OutcomeReceiverKt {
-    method @RequiresApi(31) public static <R, E extends java.lang.Throwable> android.os.OutcomeReceiver<R,E> asOutcomeReceiver(kotlin.coroutines.Continuation<? super R>);
-  }
-
-  public final class PersistableBundleKt {
-    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf(kotlin.Pair<java.lang.String,?>... pairs);
-    method @RequiresApi(21) public static android.os.PersistableBundle persistableBundleOf();
-    method @RequiresApi(21) public static android.os.PersistableBundle toPersistableBundle(java.util.Map<java.lang.String,?>);
-  }
-
-  public final class TraceKt {
-    method @Deprecated public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
-  }
-
-}
-
-package androidx.core.text {
-
-  public final class CharSequenceKt {
-    method public static inline boolean isDigitsOnly(CharSequence);
-    method public static inline int trimmedLength(CharSequence);
-  }
-
-  public final class HtmlKt {
-    method public static inline android.text.Spanned parseAsHtml(String, optional int flags, optional android.text.Html.ImageGetter? imageGetter, optional android.text.Html.TagHandler? tagHandler);
-    method public static inline String toHtml(android.text.Spanned, optional int option);
-  }
-
-  public final class LocaleKt {
-    method @RequiresApi(17) public static inline int getLayoutDirection(java.util.Locale);
-  }
-
-  public final class SpannableStringBuilderKt {
-    method public static inline android.text.SpannableStringBuilder backgroundColor(android.text.SpannableStringBuilder, @ColorInt int color, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder bold(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannedString buildSpannedString(kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder color(android.text.SpannableStringBuilder, @ColorInt int color, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder inSpans(android.text.SpannableStringBuilder, Object![] spans, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder inSpans(android.text.SpannableStringBuilder, Object span, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder italic(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder scale(android.text.SpannableStringBuilder, float proportion, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder strikeThrough(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder subscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder superscript(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-    method public static inline android.text.SpannableStringBuilder underline(android.text.SpannableStringBuilder, kotlin.jvm.functions.Function1<? super android.text.SpannableStringBuilder,kotlin.Unit> builderAction);
-  }
-
-  public final class SpannableStringKt {
-    method public static inline void clearSpans(android.text.Spannable);
-    method public static inline operator void set(android.text.Spannable, int start, int end, Object span);
-    method public static inline operator void set(android.text.Spannable, kotlin.ranges.IntRange range, Object span);
-    method public static inline android.text.Spannable toSpannable(CharSequence);
-  }
-
-  public final class SpannedStringKt {
-    method public static inline <reified T> T![]! getSpans(android.text.Spanned, optional int start, optional int end);
-    method public static inline android.text.Spanned toSpanned(CharSequence);
-  }
-
-  public final class StringKt {
-    method public static inline String htmlEncode(String);
-  }
-
-}
-
-package androidx.core.transition {
-
-  public final class TransitionKt {
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener addListener(android.transition.Transition, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onEnd, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onStart, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onCancel, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onResume, optional kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> onPause);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnCancel(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnEnd(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnPause(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnResume(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-    method @RequiresApi(19) public static inline android.transition.Transition.TransitionListener doOnStart(android.transition.Transition, kotlin.jvm.functions.Function1<? super android.transition.Transition,kotlin.Unit> action);
-  }
-
-}
-
-package androidx.core.util {
-
-  public final class AndroidXConsumerKt {
-    method public static <T> androidx.core.util.Consumer<T> asAndroidXConsumer(kotlin.coroutines.Continuation<? super T>);
-  }
-
-  public final class AtomicFileKt {
-    method @RequiresApi(17) public static inline byte[] readBytes(android.util.AtomicFile);
-    method @RequiresApi(17) public static String readText(android.util.AtomicFile, optional java.nio.charset.Charset charset);
-    method @RequiresApi(17) public static inline void tryWrite(android.util.AtomicFile, kotlin.jvm.functions.Function1<? super java.io.FileOutputStream,kotlin.Unit> block);
-    method @RequiresApi(17) public static void writeBytes(android.util.AtomicFile, byte[] array);
-    method @RequiresApi(17) public static void writeText(android.util.AtomicFile, String text, optional java.nio.charset.Charset charset);
-  }
-
-  @RequiresApi(24) public final class ConsumerKt {
-    method @RequiresApi(24) public static <T> java.util.function.Consumer<T> asConsumer(kotlin.coroutines.Continuation<? super T>);
-  }
-
-  public final class HalfKt {
-    method @RequiresApi(26) public static inline android.util.Half toHalf(@HalfFloat short);
-    method @RequiresApi(26) public static inline android.util.Half toHalf(float);
-    method @RequiresApi(26) public static inline android.util.Half toHalf(double);
-    method @RequiresApi(26) public static inline android.util.Half toHalf(String);
-  }
-
-  public final class LongSparseArrayKt {
-    method @RequiresApi(16) public static inline operator <T> boolean contains(android.util.LongSparseArray<T>, long key);
-    method @RequiresApi(16) public static inline <T> boolean containsKey(android.util.LongSparseArray<T>, long key);
-    method @RequiresApi(16) public static inline <T> boolean containsValue(android.util.LongSparseArray<T>, T? value);
-    method @RequiresApi(16) public static inline <T> void forEach(android.util.LongSparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Long,? super T,kotlin.Unit> action);
-    method @RequiresApi(16) public static inline <T> T! getOrDefault(android.util.LongSparseArray<T>, long key, T? defaultValue);
-    method @RequiresApi(16) public static inline <T> T! getOrElse(android.util.LongSparseArray<T>, long key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
-    method @RequiresApi(16) public static inline <T> int getSize(android.util.LongSparseArray<T>);
-    method @RequiresApi(16) public static inline <T> boolean isEmpty(android.util.LongSparseArray<T>);
-    method @RequiresApi(16) public static inline <T> boolean isNotEmpty(android.util.LongSparseArray<T>);
-    method @RequiresApi(16) public static <T> kotlin.collections.LongIterator keyIterator(android.util.LongSparseArray<T>);
-    method @RequiresApi(16) public static operator <T> android.util.LongSparseArray<T> plus(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
-    method @RequiresApi(16) public static <T> void putAll(android.util.LongSparseArray<T>, android.util.LongSparseArray<T> other);
-    method @RequiresApi(16) public static <T> boolean remove(android.util.LongSparseArray<T>, long key, T? value);
-    method @RequiresApi(16) public static inline operator <T> void set(android.util.LongSparseArray<T>, long key, T? value);
-    method @RequiresApi(16) public static <T> java.util.Iterator<T> valueIterator(android.util.LongSparseArray<T>);
-  }
-
-  public final class LruCacheKt {
-    method public static inline <K, V> android.util.LruCache<K,V> lruCache(int maxSize, optional kotlin.jvm.functions.Function2<? super K,? super V,java.lang.Integer> sizeOf, optional kotlin.jvm.functions.Function1<? super K,? extends V> create, optional kotlin.jvm.functions.Function4<? super java.lang.Boolean,? super K,? super V,? super V,kotlin.Unit> onEntryRemoved);
-  }
-
-  public final class PairKt {
-    method public static inline operator <F, S> F! component1(androidx.core.util.Pair<F,S>);
-    method public static inline operator <F, S> F! component1(android.util.Pair<F,S>);
-    method public static inline operator <F, S> S! component2(androidx.core.util.Pair<F,S>);
-    method public static inline operator <F, S> S! component2(android.util.Pair<F,S>);
-    method public static inline <F, S> android.util.Pair<F,S> toAndroidPair(kotlin.Pair<? extends F,? extends S>);
-    method public static inline <F, S> androidx.core.util.Pair<F,S> toAndroidXPair(kotlin.Pair<? extends F,? extends S>);
-    method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(androidx.core.util.Pair<F,S>);
-    method public static inline <F, S> kotlin.Pair<F,S> toKotlinPair(android.util.Pair<F,S>);
-  }
-
-  public final class RangeKt {
-    method @RequiresApi(21) public static inline infix <T extends java.lang.Comparable<? super T>> android.util.Range<T> and(android.util.Range<T>, android.util.Range<T> other);
-    method @RequiresApi(21) public static inline operator <T extends java.lang.Comparable<? super T>> android.util.Range<T> plus(android.util.Range<T>, T value);
-    method @RequiresApi(21) public static inline operator <T extends java.lang.Comparable<? super T>> android.util.Range<T> plus(android.util.Range<T>, android.util.Range<T> other);
-    method @RequiresApi(21) public static inline infix <T extends java.lang.Comparable<? super T>> android.util.Range<T> rangeTo(T, T that);
-    method @RequiresApi(21) public static <T extends java.lang.Comparable<? super T>> kotlin.ranges.ClosedRange<T> toClosedRange(android.util.Range<T>);
-    method @RequiresApi(21) public static <T extends java.lang.Comparable<? super T>> android.util.Range<T> toRange(kotlin.ranges.ClosedRange<T>);
-  }
-
-  public final class RunnableKt {
-    method public static Runnable asRunnable(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-  }
-
-  public final class SizeKt {
-    method @RequiresApi(21) public static inline operator int component1(android.util.Size);
-    method @RequiresApi(21) public static inline operator float component1(android.util.SizeF);
-    method public static inline operator float component1(androidx.core.util.SizeFCompat);
-    method @RequiresApi(21) public static inline operator int component2(android.util.Size);
-    method @RequiresApi(21) public static inline operator float component2(android.util.SizeF);
-    method public static inline operator float component2(androidx.core.util.SizeFCompat);
-  }
-
-  public final class SparseArrayKt {
-    method public static inline operator <T> boolean contains(android.util.SparseArray<T>, int key);
-    method public static inline <T> boolean containsKey(android.util.SparseArray<T>, int key);
-    method public static inline <T> boolean containsValue(android.util.SparseArray<T>, T? value);
-    method public static inline <T> void forEach(android.util.SparseArray<T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
-    method public static inline <T> T! getOrDefault(android.util.SparseArray<T>, int key, T? defaultValue);
-    method public static inline <T> T! getOrElse(android.util.SparseArray<T>, int key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
-    method public static inline <T> int getSize(android.util.SparseArray<T>);
-    method public static inline <T> boolean isEmpty(android.util.SparseArray<T>);
-    method public static inline <T> boolean isNotEmpty(android.util.SparseArray<T>);
-    method public static <T> kotlin.collections.IntIterator keyIterator(android.util.SparseArray<T>);
-    method public static operator <T> android.util.SparseArray<T> plus(android.util.SparseArray<T>, android.util.SparseArray<T> other);
-    method public static <T> void putAll(android.util.SparseArray<T>, android.util.SparseArray<T> other);
-    method public static <T> boolean remove(android.util.SparseArray<T>, int key, T? value);
-    method public static inline operator <T> void set(android.util.SparseArray<T>, int key, T? value);
-    method public static <T> java.util.Iterator<T> valueIterator(android.util.SparseArray<T>);
-  }
-
-  public final class SparseBooleanArrayKt {
-    method public static inline operator boolean contains(android.util.SparseBooleanArray, int key);
-    method public static inline boolean containsKey(android.util.SparseBooleanArray, int key);
-    method public static inline boolean containsValue(android.util.SparseBooleanArray, boolean value);
-    method public static inline void forEach(android.util.SparseBooleanArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Boolean,kotlin.Unit> action);
-    method public static inline boolean getOrDefault(android.util.SparseBooleanArray, int key, boolean defaultValue);
-    method public static inline boolean getOrElse(android.util.SparseBooleanArray, int key, kotlin.jvm.functions.Function0<java.lang.Boolean> defaultValue);
-    method public static inline int getSize(android.util.SparseBooleanArray);
-    method public static inline boolean isEmpty(android.util.SparseBooleanArray);
-    method public static inline boolean isNotEmpty(android.util.SparseBooleanArray);
-    method public static kotlin.collections.IntIterator keyIterator(android.util.SparseBooleanArray);
-    method public static operator android.util.SparseBooleanArray plus(android.util.SparseBooleanArray, android.util.SparseBooleanArray other);
-    method public static void putAll(android.util.SparseBooleanArray, android.util.SparseBooleanArray other);
-    method public static boolean remove(android.util.SparseBooleanArray, int key, boolean value);
-    method public static inline operator void set(android.util.SparseBooleanArray, int key, boolean value);
-    method public static kotlin.collections.BooleanIterator valueIterator(android.util.SparseBooleanArray);
-  }
-
-  public final class SparseIntArrayKt {
-    method public static inline operator boolean contains(android.util.SparseIntArray, int key);
-    method public static inline boolean containsKey(android.util.SparseIntArray, int key);
-    method public static inline boolean containsValue(android.util.SparseIntArray, int value);
-    method public static inline void forEach(android.util.SparseIntArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
-    method public static inline int getOrDefault(android.util.SparseIntArray, int key, int defaultValue);
-    method public static inline int getOrElse(android.util.SparseIntArray, int key, kotlin.jvm.functions.Function0<java.lang.Integer> defaultValue);
-    method public static inline int getSize(android.util.SparseIntArray);
-    method public static inline boolean isEmpty(android.util.SparseIntArray);
-    method public static inline boolean isNotEmpty(android.util.SparseIntArray);
-    method public static kotlin.collections.IntIterator keyIterator(android.util.SparseIntArray);
-    method public static operator android.util.SparseIntArray plus(android.util.SparseIntArray, android.util.SparseIntArray other);
-    method public static void putAll(android.util.SparseIntArray, android.util.SparseIntArray other);
-    method public static boolean remove(android.util.SparseIntArray, int key, int value);
-    method public static inline operator void set(android.util.SparseIntArray, int key, int value);
-    method public static kotlin.collections.IntIterator valueIterator(android.util.SparseIntArray);
-  }
-
-  public final class SparseLongArrayKt {
-    method @RequiresApi(18) public static inline operator boolean contains(android.util.SparseLongArray, int key);
-    method @RequiresApi(18) public static inline boolean containsKey(android.util.SparseLongArray, int key);
-    method @RequiresApi(18) public static inline boolean containsValue(android.util.SparseLongArray, long value);
-    method @RequiresApi(18) public static inline void forEach(android.util.SparseLongArray, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Long,kotlin.Unit> action);
-    method @RequiresApi(18) public static inline long getOrDefault(android.util.SparseLongArray, int key, long defaultValue);
-    method @RequiresApi(18) public static inline long getOrElse(android.util.SparseLongArray, int key, kotlin.jvm.functions.Function0<java.lang.Long> defaultValue);
-    method @RequiresApi(18) public static inline int getSize(android.util.SparseLongArray);
-    method @RequiresApi(18) public static inline boolean isEmpty(android.util.SparseLongArray);
-    method @RequiresApi(18) public static inline boolean isNotEmpty(android.util.SparseLongArray);
-    method @RequiresApi(18) public static kotlin.collections.IntIterator keyIterator(android.util.SparseLongArray);
-    method @RequiresApi(18) public static operator android.util.SparseLongArray plus(android.util.SparseLongArray, android.util.SparseLongArray other);
-    method @RequiresApi(18) public static void putAll(android.util.SparseLongArray, android.util.SparseLongArray other);
-    method @RequiresApi(18) public static boolean remove(android.util.SparseLongArray, int key, long value);
-    method @RequiresApi(18) public static inline operator void set(android.util.SparseLongArray, int key, long value);
-    method @RequiresApi(18) public static kotlin.collections.LongIterator valueIterator(android.util.SparseLongArray);
-  }
-
-}
-
-package androidx.core.view {
-
-  public final class MenuKt {
-    method public static operator boolean contains(android.view.Menu, android.view.MenuItem item);
-    method public static inline void forEach(android.view.Menu, kotlin.jvm.functions.Function1<? super android.view.MenuItem,kotlin.Unit> action);
-    method public static inline void forEachIndexed(android.view.Menu, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.view.MenuItem,kotlin.Unit> action);
-    method public static inline operator android.view.MenuItem get(android.view.Menu, int index);
-    method public static kotlin.sequences.Sequence<android.view.MenuItem> getChildren(android.view.Menu);
-    method public static inline int getSize(android.view.Menu);
-    method public static inline boolean isEmpty(android.view.Menu);
-    method public static inline boolean isNotEmpty(android.view.Menu);
-    method public static operator java.util.Iterator<android.view.MenuItem> iterator(android.view.Menu);
-    method public static inline operator void minusAssign(android.view.Menu, android.view.MenuItem item);
-  }
-
-  public final class ViewGroupKt {
-    method public static inline operator boolean contains(android.view.ViewGroup, android.view.View view);
-    method public static inline void forEach(android.view.ViewGroup, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline void forEachIndexed(android.view.ViewGroup, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super android.view.View,kotlin.Unit> action);
-    method public static operator android.view.View get(android.view.ViewGroup, int index);
-    method public static kotlin.sequences.Sequence<android.view.View> getChildren(android.view.ViewGroup);
-    method public static kotlin.sequences.Sequence<android.view.View> getDescendants(android.view.ViewGroup);
-    method public static inline kotlin.ranges.IntRange getIndices(android.view.ViewGroup);
-    method public static inline int getSize(android.view.ViewGroup);
-    method public static inline boolean isEmpty(android.view.ViewGroup);
-    method public static inline boolean isNotEmpty(android.view.ViewGroup);
-    method public static operator java.util.Iterator<android.view.View> iterator(android.view.ViewGroup);
-    method public static inline operator void minusAssign(android.view.ViewGroup, android.view.View view);
-    method public static inline operator void plusAssign(android.view.ViewGroup, android.view.View view);
-    method public static inline void setMargins(android.view.ViewGroup.MarginLayoutParams, @Px int size);
-    method public static inline void updateMargins(android.view.ViewGroup.MarginLayoutParams, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
-    method @RequiresApi(17) public static inline void updateMarginsRelative(android.view.ViewGroup.MarginLayoutParams, optional @Px int start, optional @Px int top, optional @Px int end, optional @Px int bottom);
-  }
-
-  public final class ViewKt {
-    method public static inline void doOnAttach(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline void doOnDetach(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline void doOnLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline void doOnNextLayout(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static inline androidx.core.view.OneShotPreDrawListener doOnPreDraw(android.view.View, kotlin.jvm.functions.Function1<? super android.view.View,kotlin.Unit> action);
-    method public static android.graphics.Bitmap drawToBitmap(android.view.View, optional android.graphics.Bitmap.Config config);
-    method public static kotlin.sequences.Sequence<android.view.View> getAllViews(android.view.View);
-    method public static kotlin.sequences.Sequence<android.view.ViewParent> getAncestors(android.view.View);
-    method public static inline int getMarginBottom(android.view.View);
-    method public static inline int getMarginEnd(android.view.View);
-    method public static inline int getMarginLeft(android.view.View);
-    method public static inline int getMarginRight(android.view.View);
-    method public static inline int getMarginStart(android.view.View);
-    method public static inline int getMarginTop(android.view.View);
-    method public static inline boolean isGone(android.view.View);
-    method public static inline boolean isInvisible(android.view.View);
-    method public static inline boolean isVisible(android.view.View);
-    method public static inline Runnable postDelayed(android.view.View, long delayInMillis, kotlin.jvm.functions.Function0<kotlin.Unit> action);
-    method @RequiresApi(16) public static inline Runnable postOnAnimationDelayed(android.view.View, long delayInMillis, kotlin.jvm.functions.Function0<kotlin.Unit> action);
-    method public static inline void setGone(android.view.View, boolean);
-    method public static inline void setInvisible(android.view.View, boolean);
-    method public static inline void setPadding(android.view.View, @Px int size);
-    method public static inline void setVisible(android.view.View, boolean);
-    method public static inline void updateLayoutParams(android.view.View, kotlin.jvm.functions.Function1<? super android.view.ViewGroup.LayoutParams,kotlin.Unit> block);
-    method public static inline <reified T extends android.view.ViewGroup.LayoutParams> void updateLayoutParams(android.view.View, kotlin.jvm.functions.Function1<? super T,? extends kotlin.Unit> block);
-    method public static inline void updatePadding(android.view.View, optional @Px int left, optional @Px int top, optional @Px int right, optional @Px int bottom);
-    method @RequiresApi(17) public static inline void updatePaddingRelative(android.view.View, optional @Px int start, optional @Px int top, optional @Px int end, optional @Px int bottom);
-  }
-
-}
-
-package androidx.core.widget {
-
-  public final class TextViewKt {
-    method public static inline android.text.TextWatcher addTextChangedListener(android.widget.TextView, optional kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> beforeTextChanged, optional kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> onTextChanged, optional kotlin.jvm.functions.Function1<? super android.text.Editable,kotlin.Unit> afterTextChanged);
-    method public static inline android.text.TextWatcher doAfterTextChanged(android.widget.TextView, kotlin.jvm.functions.Function1<? super android.text.Editable,kotlin.Unit> action);
-    method public static inline android.text.TextWatcher doBeforeTextChanged(android.widget.TextView, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
-    method public static inline android.text.TextWatcher doOnTextChanged(android.widget.TextView, kotlin.jvm.functions.Function4<? super java.lang.CharSequence,? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Integer,kotlin.Unit> action);
-  }
-
-}
-
diff --git a/core/core-role/src/main/java/androidx/core/role/RoleManagerCompat.java b/core/core-role/src/main/java/androidx/core/role/RoleManagerCompat.java
index d739e9b..122e0ab 100644
--- a/core/core-role/src/main/java/androidx/core/role/RoleManagerCompat.java
+++ b/core/core-role/src/main/java/androidx/core/role/RoleManagerCompat.java
@@ -72,7 +72,9 @@
     /**
      * The name of the dialer role.
      * <p>
-     * To qualify for this role, an application needs to handle the intent to dial:
+     * To qualify for this role, an application needs to handle the intent to dial, and implement
+     * an {@link android.telecom.InCallService} if the application targets
+     * {@link android.os.Build.VERSION_CODES.TIRAMISU} or higher:
      * <pre class="prettyprint">{@code
      * <activity>
      *     <intent-filter>
@@ -85,6 +87,16 @@
      *         <data android:scheme="tel" />
      *     </intent-filter>
      * </activity>
+     * <service android:permission="android.permission.BIND_INCALL_SERVICE">
+     *     <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true" />
+     *     <meta-data
+     *         android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI"
+     *         android:value="false" />
+     *     <intent-filter>
+     *         <action android:name="android.telecom.InCallService" />
+     *     </intent-filter>
+     * </service>
+     *
      * }</pre>
      * The application will be able to handle those intents by default, and gain access to phone,
      * contacts, SMS, microphone and camera.
diff --git a/core/core/api/1.8.0-beta01.txt b/core/core/api/1.8.0-beta01.txt
deleted file mode 100644
index ac52137..0000000
--- a/core/core/api/1.8.0-beta01.txt
+++ /dev/null
@@ -1,3760 +0,0 @@
-// Signature format: 4.0
-package androidx.core.accessibilityservice {
-
-  public final class AccessibilityServiceInfoCompat {
-    method public static String capabilityToString(int);
-    method public static String feedbackTypeToString(int);
-    method public static String? flagToString(int);
-    method public static int getCapabilities(android.accessibilityservice.AccessibilityServiceInfo);
-    method public static String? loadDescription(android.accessibilityservice.AccessibilityServiceInfo, android.content.pm.PackageManager);
-    field public static final int CAPABILITY_CAN_FILTER_KEY_EVENTS = 8; // 0x8
-    field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
-    field public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2; // 0x2
-    field public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1; // 0x1
-    field public static final int FEEDBACK_ALL_MASK = -1; // 0xffffffff
-    field public static final int FEEDBACK_BRAILLE = 32; // 0x20
-    field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
-    field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
-    field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
-    field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
-    field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
-  }
-
-}
-
-package androidx.core.app {
-
-  public class ActivityCompat extends androidx.core.content.ContextCompat {
-    ctor protected ActivityCompat();
-    method public static void finishAffinity(android.app.Activity);
-    method public static void finishAfterTransition(android.app.Activity);
-    method public static android.net.Uri? getReferrer(android.app.Activity);
-    method @Deprecated public static boolean invalidateOptionsMenu(android.app.Activity!);
-    method public static boolean isLaunchedFromBubble(android.app.Activity);
-    method public static void postponeEnterTransition(android.app.Activity);
-    method public static void recreate(android.app.Activity);
-    method public static androidx.core.view.DragAndDropPermissionsCompat? requestDragAndDropPermissions(android.app.Activity, android.view.DragEvent);
-    method public static void requestPermissions(android.app.Activity, String![], @IntRange(from=0) int);
-    method public static <T extends android.view.View> T requireViewById(android.app.Activity, @IdRes int);
-    method public static void setEnterSharedElementCallback(android.app.Activity, androidx.core.app.SharedElementCallback?);
-    method public static void setExitSharedElementCallback(android.app.Activity, androidx.core.app.SharedElementCallback?);
-    method public static void setLocusContext(android.app.Activity, androidx.core.content.LocusIdCompat?, android.os.Bundle?);
-    method public static void setPermissionCompatDelegate(androidx.core.app.ActivityCompat.PermissionCompatDelegate?);
-    method public static boolean shouldShowRequestPermissionRationale(android.app.Activity, String);
-    method public static void startActivityForResult(android.app.Activity, android.content.Intent, int, android.os.Bundle?);
-    method public static void startIntentSenderForResult(android.app.Activity, android.content.IntentSender, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
-    method public static void startPostponedEnterTransition(android.app.Activity);
-  }
-
-  public static interface ActivityCompat.OnRequestPermissionsResultCallback {
-    method public void onRequestPermissionsResult(int, String![], int[]);
-  }
-
-  public static interface ActivityCompat.PermissionCompatDelegate {
-    method public boolean onActivityResult(android.app.Activity, @IntRange(from=0) int, int, android.content.Intent?);
-    method public boolean requestPermissions(android.app.Activity, String![], @IntRange(from=0) int);
-  }
-
-  public final class ActivityManagerCompat {
-    method public static boolean isLowRamDevice(android.app.ActivityManager);
-  }
-
-  public class ActivityOptionsCompat {
-    ctor protected ActivityOptionsCompat();
-    method public android.graphics.Rect? getLaunchBounds();
-    method public static androidx.core.app.ActivityOptionsCompat makeBasic();
-    method public static androidx.core.app.ActivityOptionsCompat makeClipRevealAnimation(android.view.View, int, int, int, int);
-    method public static androidx.core.app.ActivityOptionsCompat makeCustomAnimation(android.content.Context, int, int);
-    method public static androidx.core.app.ActivityOptionsCompat makeScaleUpAnimation(android.view.View, int, int, int, int);
-    method public static androidx.core.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, android.view.View, String);
-    method public static androidx.core.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, androidx.core.util.Pair<android.view.View!,java.lang.String!>!...);
-    method public static androidx.core.app.ActivityOptionsCompat makeTaskLaunchBehind();
-    method public static androidx.core.app.ActivityOptionsCompat makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
-    method public void requestUsageTimeReport(android.app.PendingIntent);
-    method public androidx.core.app.ActivityOptionsCompat setLaunchBounds(android.graphics.Rect?);
-    method public android.os.Bundle? toBundle();
-    method public void update(androidx.core.app.ActivityOptionsCompat);
-    field public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
-    field public static final String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
-  }
-
-  public final class AlarmManagerCompat {
-    method public static void setAlarmClock(android.app.AlarmManager, long, android.app.PendingIntent, android.app.PendingIntent);
-    method public static void setAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
-    method public static void setExact(android.app.AlarmManager, int, long, android.app.PendingIntent);
-    method public static void setExactAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
-  }
-
-  @RequiresApi(28) public class AppComponentFactory extends android.app.AppComponentFactory {
-    ctor public AppComponentFactory();
-    method public final android.app.Activity instantiateActivity(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public android.app.Activity instantiateActivityCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public final android.app.Application instantiateApplication(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public android.app.Application instantiateApplicationCompat(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public final android.content.ContentProvider instantiateProvider(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public android.content.ContentProvider instantiateProviderCompat(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public final android.content.BroadcastReceiver instantiateReceiver(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public android.content.BroadcastReceiver instantiateReceiverCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public final android.app.Service instantiateService(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public android.app.Service instantiateServiceCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-  }
-
-  public class AppLaunchChecker {
-    ctor @Deprecated public AppLaunchChecker();
-    method public static boolean hasStartedFromLauncher(android.content.Context);
-    method public static void onActivityCreate(android.app.Activity);
-  }
-
-  public final class AppOpsManagerCompat {
-    method public static int checkOrNoteProxyOp(android.content.Context, int, String, String);
-    method public static int noteOp(android.content.Context, String, int, String);
-    method public static int noteOpNoThrow(android.content.Context, String, int, String);
-    method public static int noteProxyOp(android.content.Context, String, String);
-    method public static int noteProxyOpNoThrow(android.content.Context, String, String);
-    method public static String? permissionToOp(String);
-    field public static final int MODE_ALLOWED = 0; // 0x0
-    field public static final int MODE_DEFAULT = 3; // 0x3
-    field public static final int MODE_ERRORED = 2; // 0x2
-    field public static final int MODE_IGNORED = 1; // 0x1
-  }
-
-  public final class BundleCompat {
-    method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
-    method public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
-  }
-
-  public class DialogCompat {
-    method public static android.view.View requireViewById(android.app.Dialog, int);
-  }
-
-  public class FrameMetricsAggregator {
-    ctor public FrameMetricsAggregator();
-    ctor public FrameMetricsAggregator(int);
-    method public void add(android.app.Activity);
-    method public android.util.SparseIntArray![]? getMetrics();
-    method public android.util.SparseIntArray![]? remove(android.app.Activity);
-    method public android.util.SparseIntArray![]? reset();
-    method public android.util.SparseIntArray![]? stop();
-    field public static final int ANIMATION_DURATION = 256; // 0x100
-    field public static final int ANIMATION_INDEX = 8; // 0x8
-    field public static final int COMMAND_DURATION = 32; // 0x20
-    field public static final int COMMAND_INDEX = 5; // 0x5
-    field public static final int DELAY_DURATION = 128; // 0x80
-    field public static final int DELAY_INDEX = 7; // 0x7
-    field public static final int DRAW_DURATION = 8; // 0x8
-    field public static final int DRAW_INDEX = 3; // 0x3
-    field public static final int EVERY_DURATION = 511; // 0x1ff
-    field public static final int INPUT_DURATION = 2; // 0x2
-    field public static final int INPUT_INDEX = 1; // 0x1
-    field public static final int LAYOUT_MEASURE_DURATION = 4; // 0x4
-    field public static final int LAYOUT_MEASURE_INDEX = 2; // 0x2
-    field public static final int SWAP_DURATION = 64; // 0x40
-    field public static final int SWAP_INDEX = 6; // 0x6
-    field public static final int SYNC_DURATION = 16; // 0x10
-    field public static final int SYNC_INDEX = 4; // 0x4
-    field public static final int TOTAL_DURATION = 1; // 0x1
-    field public static final int TOTAL_INDEX = 0; // 0x0
-  }
-
-  @Deprecated public abstract class JobIntentService extends android.app.Service {
-    ctor @Deprecated public JobIntentService();
-    method @Deprecated public static void enqueueWork(android.content.Context, Class<?>, int, android.content.Intent);
-    method @Deprecated public static void enqueueWork(android.content.Context, android.content.ComponentName, int, android.content.Intent);
-    method @Deprecated public boolean isStopped();
-    method @Deprecated public android.os.IBinder! onBind(android.content.Intent);
-    method @Deprecated protected abstract void onHandleWork(android.content.Intent);
-    method @Deprecated public boolean onStopCurrentWork();
-    method @Deprecated public void setInterruptIfStopped(boolean);
-  }
-
-  public final class MultiWindowModeChangedInfo {
-    ctor public MultiWindowModeChangedInfo(boolean);
-    ctor @RequiresApi(26) public MultiWindowModeChangedInfo(boolean, android.content.res.Configuration);
-    method @RequiresApi(26) public android.content.res.Configuration getNewConfig();
-    method public boolean isInMultiWindowMode();
-  }
-
-  public final class NavUtils {
-    method public static android.content.Intent? getParentActivityIntent(android.app.Activity);
-    method public static android.content.Intent? getParentActivityIntent(android.content.Context, Class<?>) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public static android.content.Intent? getParentActivityIntent(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public static String? getParentActivityName(android.app.Activity);
-    method public static String? getParentActivityName(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public static void navigateUpFromSameTask(android.app.Activity);
-    method public static void navigateUpTo(android.app.Activity, android.content.Intent);
-    method public static boolean shouldUpRecreateTask(android.app.Activity, android.content.Intent);
-    field public static final String PARENT_ACTIVITY = "android.support.PARENT_ACTIVITY";
-  }
-
-  public class NotificationChannelCompat {
-    method public boolean canBubble();
-    method public boolean canBypassDnd();
-    method public boolean canShowBadge();
-    method public android.media.AudioAttributes? getAudioAttributes();
-    method public String? getConversationId();
-    method public String? getDescription();
-    method public String? getGroup();
-    method public String getId();
-    method public int getImportance();
-    method public int getLightColor();
-    method public int getLockscreenVisibility();
-    method public CharSequence? getName();
-    method public String? getParentChannelId();
-    method public android.net.Uri? getSound();
-    method public long[]? getVibrationPattern();
-    method public boolean isImportantConversation();
-    method public boolean shouldShowLights();
-    method public boolean shouldVibrate();
-    method public androidx.core.app.NotificationChannelCompat.Builder toBuilder();
-    field public static final String DEFAULT_CHANNEL_ID = "miscellaneous";
-  }
-
-  public static class NotificationChannelCompat.Builder {
-    ctor public NotificationChannelCompat.Builder(String, int);
-    method public androidx.core.app.NotificationChannelCompat build();
-    method public androidx.core.app.NotificationChannelCompat.Builder setConversationId(String, String);
-    method public androidx.core.app.NotificationChannelCompat.Builder setDescription(String?);
-    method public androidx.core.app.NotificationChannelCompat.Builder setGroup(String?);
-    method public androidx.core.app.NotificationChannelCompat.Builder setImportance(int);
-    method public androidx.core.app.NotificationChannelCompat.Builder setLightColor(int);
-    method public androidx.core.app.NotificationChannelCompat.Builder setLightsEnabled(boolean);
-    method public androidx.core.app.NotificationChannelCompat.Builder setName(CharSequence?);
-    method public androidx.core.app.NotificationChannelCompat.Builder setShowBadge(boolean);
-    method public androidx.core.app.NotificationChannelCompat.Builder setSound(android.net.Uri?, android.media.AudioAttributes?);
-    method public androidx.core.app.NotificationChannelCompat.Builder setVibrationEnabled(boolean);
-    method public androidx.core.app.NotificationChannelCompat.Builder setVibrationPattern(long[]?);
-  }
-
-  public class NotificationChannelGroupCompat {
-    method public java.util.List<androidx.core.app.NotificationChannelCompat!> getChannels();
-    method public String? getDescription();
-    method public String getId();
-    method public CharSequence? getName();
-    method public boolean isBlocked();
-    method public androidx.core.app.NotificationChannelGroupCompat.Builder toBuilder();
-  }
-
-  public static class NotificationChannelGroupCompat.Builder {
-    ctor public NotificationChannelGroupCompat.Builder(String);
-    method public androidx.core.app.NotificationChannelGroupCompat build();
-    method public androidx.core.app.NotificationChannelGroupCompat.Builder setDescription(String?);
-    method public androidx.core.app.NotificationChannelGroupCompat.Builder setName(CharSequence?);
-  }
-
-  public class NotificationCompat {
-    ctor @Deprecated public NotificationCompat();
-    method public static androidx.core.app.NotificationCompat.Action? getAction(android.app.Notification, int);
-    method public static int getActionCount(android.app.Notification);
-    method public static boolean getAllowSystemGeneratedContextualActions(android.app.Notification);
-    method public static boolean getAutoCancel(android.app.Notification);
-    method public static int getBadgeIconType(android.app.Notification);
-    method public static androidx.core.app.NotificationCompat.BubbleMetadata? getBubbleMetadata(android.app.Notification);
-    method public static String? getCategory(android.app.Notification);
-    method public static String? getChannelId(android.app.Notification);
-    method public static int getColor(android.app.Notification);
-    method @RequiresApi(19) public static CharSequence? getContentInfo(android.app.Notification);
-    method @RequiresApi(19) public static CharSequence? getContentText(android.app.Notification);
-    method @RequiresApi(19) public static CharSequence? getContentTitle(android.app.Notification);
-    method public static android.os.Bundle? getExtras(android.app.Notification);
-    method public static String? getGroup(android.app.Notification);
-    method public static int getGroupAlertBehavior(android.app.Notification);
-    method @RequiresApi(21) public static java.util.List<androidx.core.app.NotificationCompat.Action!> getInvisibleActions(android.app.Notification);
-    method public static boolean getLocalOnly(android.app.Notification);
-    method public static androidx.core.content.LocusIdCompat? getLocusId(android.app.Notification);
-    method public static boolean getOngoing(android.app.Notification);
-    method public static boolean getOnlyAlertOnce(android.app.Notification);
-    method public static java.util.List<androidx.core.app.Person!> getPeople(android.app.Notification);
-    method public static android.app.Notification? getPublicVersion(android.app.Notification);
-    method public static CharSequence? getSettingsText(android.app.Notification);
-    method public static String? getShortcutId(android.app.Notification);
-    method @RequiresApi(19) public static boolean getShowWhen(android.app.Notification);
-    method public static String? getSortKey(android.app.Notification);
-    method @RequiresApi(19) public static CharSequence? getSubText(android.app.Notification);
-    method public static long getTimeoutAfter(android.app.Notification);
-    method @RequiresApi(19) public static boolean getUsesChronometer(android.app.Notification);
-    method public static int getVisibility(android.app.Notification);
-    method public static boolean isGroupSummary(android.app.Notification);
-    field public static final int BADGE_ICON_LARGE = 2; // 0x2
-    field public static final int BADGE_ICON_NONE = 0; // 0x0
-    field public static final int BADGE_ICON_SMALL = 1; // 0x1
-    field public static final String CATEGORY_ALARM = "alarm";
-    field public static final String CATEGORY_CALL = "call";
-    field public static final String CATEGORY_EMAIL = "email";
-    field public static final String CATEGORY_ERROR = "err";
-    field public static final String CATEGORY_EVENT = "event";
-    field public static final String CATEGORY_LOCATION_SHARING = "location_sharing";
-    field public static final String CATEGORY_MESSAGE = "msg";
-    field public static final String CATEGORY_MISSED_CALL = "missed_call";
-    field public static final String CATEGORY_NAVIGATION = "navigation";
-    field public static final String CATEGORY_PROGRESS = "progress";
-    field public static final String CATEGORY_PROMO = "promo";
-    field public static final String CATEGORY_RECOMMENDATION = "recommendation";
-    field public static final String CATEGORY_REMINDER = "reminder";
-    field public static final String CATEGORY_SERVICE = "service";
-    field public static final String CATEGORY_SOCIAL = "social";
-    field public static final String CATEGORY_STATUS = "status";
-    field public static final String CATEGORY_STOPWATCH = "stopwatch";
-    field public static final String CATEGORY_SYSTEM = "sys";
-    field public static final String CATEGORY_TRANSPORT = "transport";
-    field public static final String CATEGORY_WORKOUT = "workout";
-    field @ColorInt public static final int COLOR_DEFAULT = 0; // 0x0
-    field public static final int DEFAULT_ALL = -1; // 0xffffffff
-    field public static final int DEFAULT_LIGHTS = 4; // 0x4
-    field public static final int DEFAULT_SOUND = 1; // 0x1
-    field public static final int DEFAULT_VIBRATE = 2; // 0x2
-    field public static final String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents";
-    field public static final String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
-    field public static final String EXTRA_BIG_TEXT = "android.bigText";
-    field public static final String EXTRA_CHANNEL_GROUP_ID = "android.intent.extra.CHANNEL_GROUP_ID";
-    field public static final String EXTRA_CHANNEL_ID = "android.intent.extra.CHANNEL_ID";
-    field public static final String EXTRA_CHRONOMETER_COUNT_DOWN = "android.chronometerCountDown";
-    field public static final String EXTRA_COLORIZED = "android.colorized";
-    field public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions";
-    field public static final String EXTRA_COMPAT_TEMPLATE = "androidx.core.app.extra.COMPAT_TEMPLATE";
-    field public static final String EXTRA_CONVERSATION_TITLE = "android.conversationTitle";
-    field public static final String EXTRA_HIDDEN_CONVERSATION_TITLE = "android.hiddenConversationTitle";
-    field public static final String EXTRA_HISTORIC_MESSAGES = "android.messages.historic";
-    field public static final String EXTRA_INFO_TEXT = "android.infoText";
-    field public static final String EXTRA_IS_GROUP_CONVERSATION = "android.isGroupConversation";
-    field public static final String EXTRA_LARGE_ICON = "android.largeIcon";
-    field public static final String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
-    field public static final String EXTRA_MEDIA_SESSION = "android.mediaSession";
-    field public static final String EXTRA_MESSAGES = "android.messages";
-    field public static final String EXTRA_MESSAGING_STYLE_USER = "android.messagingStyleUser";
-    field public static final String EXTRA_NOTIFICATION_ID = "android.intent.extra.NOTIFICATION_ID";
-    field public static final String EXTRA_NOTIFICATION_TAG = "android.intent.extra.NOTIFICATION_TAG";
-    field @Deprecated public static final String EXTRA_PEOPLE = "android.people";
-    field public static final String EXTRA_PEOPLE_LIST = "android.people.list";
-    field public static final String EXTRA_PICTURE = "android.picture";
-    field public static final String EXTRA_PICTURE_CONTENT_DESCRIPTION = "android.pictureContentDescription";
-    field public static final String EXTRA_PROGRESS = "android.progress";
-    field public static final String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
-    field public static final String EXTRA_PROGRESS_MAX = "android.progressMax";
-    field public static final String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
-    field public static final String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
-    field public static final String EXTRA_SHOW_BIG_PICTURE_WHEN_COLLAPSED = "android.showBigPictureWhenCollapsed";
-    field public static final String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
-    field public static final String EXTRA_SHOW_WHEN = "android.showWhen";
-    field public static final String EXTRA_SMALL_ICON = "android.icon";
-    field public static final String EXTRA_SUB_TEXT = "android.subText";
-    field public static final String EXTRA_SUMMARY_TEXT = "android.summaryText";
-    field public static final String EXTRA_TEMPLATE = "android.template";
-    field public static final String EXTRA_TEXT = "android.text";
-    field public static final String EXTRA_TEXT_LINES = "android.textLines";
-    field public static final String EXTRA_TITLE = "android.title";
-    field public static final String EXTRA_TITLE_BIG = "android.title.big";
-    field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
-    field public static final int FLAG_BUBBLE = 4096; // 0x1000
-    field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
-    field public static final int FLAG_GROUP_SUMMARY = 512; // 0x200
-    field @Deprecated public static final int FLAG_HIGH_PRIORITY = 128; // 0x80
-    field public static final int FLAG_INSISTENT = 4; // 0x4
-    field public static final int FLAG_LOCAL_ONLY = 256; // 0x100
-    field public static final int FLAG_NO_CLEAR = 32; // 0x20
-    field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
-    field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
-    field public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
-    field public static final int FOREGROUND_SERVICE_DEFAULT = 0; // 0x0
-    field public static final int FOREGROUND_SERVICE_DEFERRED = 2; // 0x2
-    field public static final int FOREGROUND_SERVICE_IMMEDIATE = 1; // 0x1
-    field public static final int GROUP_ALERT_ALL = 0; // 0x0
-    field public static final int GROUP_ALERT_CHILDREN = 2; // 0x2
-    field public static final int GROUP_ALERT_SUMMARY = 1; // 0x1
-    field public static final String GROUP_KEY_SILENT = "silent";
-    field public static final String INTENT_CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
-    field public static final int PRIORITY_DEFAULT = 0; // 0x0
-    field public static final int PRIORITY_HIGH = 1; // 0x1
-    field public static final int PRIORITY_LOW = -1; // 0xffffffff
-    field public static final int PRIORITY_MAX = 2; // 0x2
-    field public static final int PRIORITY_MIN = -2; // 0xfffffffe
-    field public static final int STREAM_DEFAULT = -1; // 0xffffffff
-    field public static final int VISIBILITY_PRIVATE = 0; // 0x0
-    field public static final int VISIBILITY_PUBLIC = 1; // 0x1
-    field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
-  }
-
-  public static class NotificationCompat.Action {
-    ctor public NotificationCompat.Action(int, CharSequence?, android.app.PendingIntent?);
-    ctor public NotificationCompat.Action(androidx.core.graphics.drawable.IconCompat?, CharSequence?, android.app.PendingIntent?);
-    method public android.app.PendingIntent? getActionIntent();
-    method public boolean getAllowGeneratedReplies();
-    method public androidx.core.app.RemoteInput![]? getDataOnlyRemoteInputs();
-    method public android.os.Bundle getExtras();
-    method @Deprecated public int getIcon();
-    method public androidx.core.graphics.drawable.IconCompat? getIconCompat();
-    method public androidx.core.app.RemoteInput![]? getRemoteInputs();
-    method @androidx.core.app.NotificationCompat.Action.SemanticAction public int getSemanticAction();
-    method public boolean getShowsUserInterface();
-    method public CharSequence? getTitle();
-    method public boolean isAuthenticationRequired();
-    method public boolean isContextual();
-    field public static final int SEMANTIC_ACTION_ARCHIVE = 5; // 0x5
-    field public static final int SEMANTIC_ACTION_CALL = 10; // 0xa
-    field public static final int SEMANTIC_ACTION_DELETE = 4; // 0x4
-    field public static final int SEMANTIC_ACTION_MARK_AS_READ = 2; // 0x2
-    field public static final int SEMANTIC_ACTION_MARK_AS_UNREAD = 3; // 0x3
-    field public static final int SEMANTIC_ACTION_MUTE = 6; // 0x6
-    field public static final int SEMANTIC_ACTION_NONE = 0; // 0x0
-    field public static final int SEMANTIC_ACTION_REPLY = 1; // 0x1
-    field public static final int SEMANTIC_ACTION_THUMBS_DOWN = 9; // 0x9
-    field public static final int SEMANTIC_ACTION_THUMBS_UP = 8; // 0x8
-    field public static final int SEMANTIC_ACTION_UNMUTE = 7; // 0x7
-    field public android.app.PendingIntent! actionIntent;
-    field @Deprecated public int icon;
-    field public CharSequence! title;
-  }
-
-  public static final class NotificationCompat.Action.Builder {
-    ctor public NotificationCompat.Action.Builder(androidx.core.graphics.drawable.IconCompat?, CharSequence?, android.app.PendingIntent?);
-    ctor public NotificationCompat.Action.Builder(int, CharSequence?, android.app.PendingIntent?);
-    ctor public NotificationCompat.Action.Builder(androidx.core.app.NotificationCompat.Action);
-    method public androidx.core.app.NotificationCompat.Action.Builder addExtras(android.os.Bundle?);
-    method public androidx.core.app.NotificationCompat.Action.Builder addRemoteInput(androidx.core.app.RemoteInput?);
-    method public androidx.core.app.NotificationCompat.Action build();
-    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Extender);
-    method public android.os.Bundle getExtras();
-    method public androidx.core.app.NotificationCompat.Action.Builder setAllowGeneratedReplies(boolean);
-    method public androidx.core.app.NotificationCompat.Action.Builder setAuthenticationRequired(boolean);
-    method public androidx.core.app.NotificationCompat.Action.Builder setContextual(boolean);
-    method public androidx.core.app.NotificationCompat.Action.Builder setSemanticAction(@androidx.core.app.NotificationCompat.Action.SemanticAction int);
-    method public androidx.core.app.NotificationCompat.Action.Builder setShowsUserInterface(boolean);
-  }
-
-  public static interface NotificationCompat.Action.Extender {
-    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Builder);
-  }
-
-  @IntDef({androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_NONE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_REPLY, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_UNREAD, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_DELETE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_ARCHIVE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MUTE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_UNMUTE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_THUMBS_UP, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_THUMBS_DOWN, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_CALL}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.Action.SemanticAction {
-  }
-
-  public static final class NotificationCompat.Action.WearableExtender implements androidx.core.app.NotificationCompat.Action.Extender {
-    ctor public NotificationCompat.Action.WearableExtender();
-    ctor public NotificationCompat.Action.WearableExtender(androidx.core.app.NotificationCompat.Action);
-    method public androidx.core.app.NotificationCompat.Action.WearableExtender clone();
-    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Builder);
-    method @Deprecated public CharSequence? getCancelLabel();
-    method @Deprecated public CharSequence? getConfirmLabel();
-    method public boolean getHintDisplayActionInline();
-    method public boolean getHintLaunchesActivity();
-    method @Deprecated public CharSequence? getInProgressLabel();
-    method public boolean isAvailableOffline();
-    method public androidx.core.app.NotificationCompat.Action.WearableExtender setAvailableOffline(boolean);
-    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setCancelLabel(CharSequence?);
-    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setConfirmLabel(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Action.WearableExtender setHintDisplayActionInline(boolean);
-    method public androidx.core.app.NotificationCompat.Action.WearableExtender setHintLaunchesActivity(boolean);
-    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setInProgressLabel(CharSequence?);
-  }
-
-  public static class NotificationCompat.BigPictureStyle extends androidx.core.app.NotificationCompat.Style {
-    ctor public NotificationCompat.BigPictureStyle();
-    ctor public NotificationCompat.BigPictureStyle(androidx.core.app.NotificationCompat.Builder?);
-    method public androidx.core.app.NotificationCompat.BigPictureStyle bigLargeIcon(android.graphics.Bitmap?);
-    method public androidx.core.app.NotificationCompat.BigPictureStyle bigPicture(android.graphics.Bitmap?);
-    method public androidx.core.app.NotificationCompat.BigPictureStyle setBigContentTitle(CharSequence?);
-    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle setContentDescription(CharSequence?);
-    method public androidx.core.app.NotificationCompat.BigPictureStyle setSummaryText(CharSequence?);
-    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle showBigPictureWhenCollapsed(boolean);
-  }
-
-  public static class NotificationCompat.BigTextStyle extends androidx.core.app.NotificationCompat.Style {
-    ctor public NotificationCompat.BigTextStyle();
-    ctor public NotificationCompat.BigTextStyle(androidx.core.app.NotificationCompat.Builder?);
-    method public androidx.core.app.NotificationCompat.BigTextStyle bigText(CharSequence?);
-    method public androidx.core.app.NotificationCompat.BigTextStyle setBigContentTitle(CharSequence?);
-    method public androidx.core.app.NotificationCompat.BigTextStyle setSummaryText(CharSequence?);
-  }
-
-  public static final class NotificationCompat.BubbleMetadata {
-    method public static androidx.core.app.NotificationCompat.BubbleMetadata? fromPlatform(android.app.Notification.BubbleMetadata?);
-    method public boolean getAutoExpandBubble();
-    method public android.app.PendingIntent? getDeleteIntent();
-    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getDesiredHeight();
-    method @DimenRes public int getDesiredHeightResId();
-    method public androidx.core.graphics.drawable.IconCompat? getIcon();
-    method public android.app.PendingIntent? getIntent();
-    method public String? getShortcutId();
-    method public boolean isNotificationSuppressed();
-    method public static android.app.Notification.BubbleMetadata? toPlatform(androidx.core.app.NotificationCompat.BubbleMetadata?);
-  }
-
-  public static final class NotificationCompat.BubbleMetadata.Builder {
-    ctor @Deprecated public NotificationCompat.BubbleMetadata.Builder();
-    ctor @RequiresApi(30) public NotificationCompat.BubbleMetadata.Builder(String);
-    ctor public NotificationCompat.BubbleMetadata.Builder(android.app.PendingIntent, androidx.core.graphics.drawable.IconCompat);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata build();
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setAutoExpandBubble(boolean);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDeleteIntent(android.app.PendingIntent?);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDesiredHeight(@Dimension(unit=androidx.annotation.Dimension.DP) int);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setIcon(androidx.core.graphics.drawable.IconCompat);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setIntent(android.app.PendingIntent);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setSuppressNotification(boolean);
-  }
-
-  public static class NotificationCompat.Builder {
-    ctor @RequiresApi(19) public NotificationCompat.Builder(android.content.Context, android.app.Notification);
-    ctor public NotificationCompat.Builder(android.content.Context, String);
-    ctor @Deprecated public NotificationCompat.Builder(android.content.Context);
-    method public androidx.core.app.NotificationCompat.Builder addAction(int, CharSequence?, android.app.PendingIntent?);
-    method public androidx.core.app.NotificationCompat.Builder addAction(androidx.core.app.NotificationCompat.Action?);
-    method public androidx.core.app.NotificationCompat.Builder addExtras(android.os.Bundle?);
-    method @RequiresApi(21) public androidx.core.app.NotificationCompat.Builder addInvisibleAction(int, CharSequence?, android.app.PendingIntent?);
-    method @RequiresApi(21) public androidx.core.app.NotificationCompat.Builder addInvisibleAction(androidx.core.app.NotificationCompat.Action?);
-    method @Deprecated public androidx.core.app.NotificationCompat.Builder addPerson(String?);
-    method public androidx.core.app.NotificationCompat.Builder addPerson(androidx.core.app.Person?);
-    method public android.app.Notification build();
-    method public androidx.core.app.NotificationCompat.Builder clearActions();
-    method public androidx.core.app.NotificationCompat.Builder clearInvisibleActions();
-    method public androidx.core.app.NotificationCompat.Builder clearPeople();
-    method public android.widget.RemoteViews? createBigContentView();
-    method public android.widget.RemoteViews? createContentView();
-    method public android.widget.RemoteViews? createHeadsUpContentView();
-    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Extender);
-    method public android.os.Bundle getExtras();
-    method @Deprecated public android.app.Notification getNotification();
-    method protected static CharSequence? limitCharSequenceLength(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Builder setAllowSystemGeneratedContextualActions(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setAutoCancel(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setBadgeIconType(int);
-    method public androidx.core.app.NotificationCompat.Builder setBubbleMetadata(androidx.core.app.NotificationCompat.BubbleMetadata?);
-    method public androidx.core.app.NotificationCompat.Builder setCategory(String?);
-    method public androidx.core.app.NotificationCompat.Builder setChannelId(String);
-    method @RequiresApi(24) public androidx.core.app.NotificationCompat.Builder setChronometerCountDown(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setColor(@ColorInt int);
-    method public androidx.core.app.NotificationCompat.Builder setColorized(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setContent(android.widget.RemoteViews?);
-    method public androidx.core.app.NotificationCompat.Builder setContentInfo(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Builder setContentIntent(android.app.PendingIntent?);
-    method public androidx.core.app.NotificationCompat.Builder setContentText(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Builder setContentTitle(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Builder setCustomBigContentView(android.widget.RemoteViews?);
-    method public androidx.core.app.NotificationCompat.Builder setCustomContentView(android.widget.RemoteViews?);
-    method public androidx.core.app.NotificationCompat.Builder setCustomHeadsUpContentView(android.widget.RemoteViews?);
-    method public androidx.core.app.NotificationCompat.Builder setDefaults(int);
-    method public androidx.core.app.NotificationCompat.Builder setDeleteIntent(android.app.PendingIntent?);
-    method public androidx.core.app.NotificationCompat.Builder setExtras(android.os.Bundle?);
-    method public androidx.core.app.NotificationCompat.Builder setForegroundServiceBehavior(int);
-    method public androidx.core.app.NotificationCompat.Builder setFullScreenIntent(android.app.PendingIntent?, boolean);
-    method public androidx.core.app.NotificationCompat.Builder setGroup(String?);
-    method public androidx.core.app.NotificationCompat.Builder setGroupAlertBehavior(int);
-    method public androidx.core.app.NotificationCompat.Builder setGroupSummary(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setLargeIcon(android.graphics.Bitmap?);
-    method public androidx.core.app.NotificationCompat.Builder setLights(@ColorInt int, int, int);
-    method public androidx.core.app.NotificationCompat.Builder setLocalOnly(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setLocusId(androidx.core.content.LocusIdCompat?);
-    method @Deprecated public androidx.core.app.NotificationCompat.Builder setNotificationSilent();
-    method public androidx.core.app.NotificationCompat.Builder setNumber(int);
-    method public androidx.core.app.NotificationCompat.Builder setOngoing(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setOnlyAlertOnce(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setPriority(int);
-    method public androidx.core.app.NotificationCompat.Builder setProgress(int, int, boolean);
-    method public androidx.core.app.NotificationCompat.Builder setPublicVersion(android.app.Notification?);
-    method public androidx.core.app.NotificationCompat.Builder setRemoteInputHistory(CharSequence![]?);
-    method public androidx.core.app.NotificationCompat.Builder setSettingsText(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Builder setShortcutId(String?);
-    method public androidx.core.app.NotificationCompat.Builder setShortcutInfo(androidx.core.content.pm.ShortcutInfoCompat?);
-    method public androidx.core.app.NotificationCompat.Builder setShowWhen(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setSilent(boolean);
-    method @RequiresApi(23) public androidx.core.app.NotificationCompat.Builder setSmallIcon(androidx.core.graphics.drawable.IconCompat);
-    method public androidx.core.app.NotificationCompat.Builder setSmallIcon(int);
-    method public androidx.core.app.NotificationCompat.Builder setSmallIcon(int, int);
-    method public androidx.core.app.NotificationCompat.Builder setSortKey(String?);
-    method public androidx.core.app.NotificationCompat.Builder setSound(android.net.Uri?);
-    method public androidx.core.app.NotificationCompat.Builder setSound(android.net.Uri?, int);
-    method public androidx.core.app.NotificationCompat.Builder setStyle(androidx.core.app.NotificationCompat.Style?);
-    method public androidx.core.app.NotificationCompat.Builder setSubText(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Builder setTicker(CharSequence?);
-    method @Deprecated public androidx.core.app.NotificationCompat.Builder setTicker(CharSequence?, android.widget.RemoteViews?);
-    method public androidx.core.app.NotificationCompat.Builder setTimeoutAfter(long);
-    method public androidx.core.app.NotificationCompat.Builder setUsesChronometer(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setVibrate(long[]?);
-    method public androidx.core.app.NotificationCompat.Builder setVisibility(int);
-    method public androidx.core.app.NotificationCompat.Builder setWhen(long);
-    field @Deprecated public java.util.ArrayList<java.lang.String!>! mPeople;
-  }
-
-  public static final class NotificationCompat.CarExtender implements androidx.core.app.NotificationCompat.Extender {
-    ctor public NotificationCompat.CarExtender();
-    ctor public NotificationCompat.CarExtender(android.app.Notification);
-    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
-    method @ColorInt public int getColor();
-    method public android.graphics.Bitmap? getLargeIcon();
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation? getUnreadConversation();
-    method public androidx.core.app.NotificationCompat.CarExtender setColor(@ColorInt int);
-    method public androidx.core.app.NotificationCompat.CarExtender setLargeIcon(android.graphics.Bitmap?);
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender setUnreadConversation(androidx.core.app.NotificationCompat.CarExtender.UnreadConversation?);
-  }
-
-  @Deprecated public static class NotificationCompat.CarExtender.UnreadConversation {
-    method @Deprecated public long getLatestTimestamp();
-    method @Deprecated public String![]? getMessages();
-    method @Deprecated public String? getParticipant();
-    method @Deprecated public String![]? getParticipants();
-    method @Deprecated public android.app.PendingIntent? getReadPendingIntent();
-    method @Deprecated public androidx.core.app.RemoteInput? getRemoteInput();
-    method @Deprecated public android.app.PendingIntent? getReplyPendingIntent();
-  }
-
-  @Deprecated public static class NotificationCompat.CarExtender.UnreadConversation.Builder {
-    ctor @Deprecated public NotificationCompat.CarExtender.UnreadConversation.Builder(String);
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder addMessage(String?);
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation build();
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setLatestTimestamp(long);
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReadPendingIntent(android.app.PendingIntent?);
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReplyAction(android.app.PendingIntent?, androidx.core.app.RemoteInput?);
-  }
-
-  public static class NotificationCompat.DecoratedCustomViewStyle extends androidx.core.app.NotificationCompat.Style {
-    ctor public NotificationCompat.DecoratedCustomViewStyle();
-  }
-
-  public static interface NotificationCompat.Extender {
-    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
-  }
-
-  public static class NotificationCompat.InboxStyle extends androidx.core.app.NotificationCompat.Style {
-    ctor public NotificationCompat.InboxStyle();
-    ctor public NotificationCompat.InboxStyle(androidx.core.app.NotificationCompat.Builder?);
-    method public androidx.core.app.NotificationCompat.InboxStyle addLine(CharSequence?);
-    method public androidx.core.app.NotificationCompat.InboxStyle setBigContentTitle(CharSequence?);
-    method public androidx.core.app.NotificationCompat.InboxStyle setSummaryText(CharSequence?);
-  }
-
-  public static class NotificationCompat.MessagingStyle extends androidx.core.app.NotificationCompat.Style {
-    ctor @Deprecated public NotificationCompat.MessagingStyle(CharSequence);
-    ctor public NotificationCompat.MessagingStyle(androidx.core.app.Person);
-    method public void addCompatExtras(android.os.Bundle);
-    method public androidx.core.app.NotificationCompat.MessagingStyle addHistoricMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message?);
-    method @Deprecated public androidx.core.app.NotificationCompat.MessagingStyle addMessage(CharSequence?, long, CharSequence?);
-    method public androidx.core.app.NotificationCompat.MessagingStyle addMessage(CharSequence?, long, androidx.core.app.Person?);
-    method public androidx.core.app.NotificationCompat.MessagingStyle addMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message?);
-    method public static androidx.core.app.NotificationCompat.MessagingStyle? extractMessagingStyleFromNotification(android.app.Notification);
-    method public CharSequence? getConversationTitle();
-    method public java.util.List<androidx.core.app.NotificationCompat.MessagingStyle.Message!> getHistoricMessages();
-    method public java.util.List<androidx.core.app.NotificationCompat.MessagingStyle.Message!> getMessages();
-    method public androidx.core.app.Person getUser();
-    method @Deprecated public CharSequence? getUserDisplayName();
-    method public boolean isGroupConversation();
-    method public androidx.core.app.NotificationCompat.MessagingStyle setConversationTitle(CharSequence?);
-    method public androidx.core.app.NotificationCompat.MessagingStyle setGroupConversation(boolean);
-    field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
-  }
-
-  public static final class NotificationCompat.MessagingStyle.Message {
-    ctor public NotificationCompat.MessagingStyle.Message(CharSequence?, long, androidx.core.app.Person?);
-    ctor @Deprecated public NotificationCompat.MessagingStyle.Message(CharSequence?, long, CharSequence?);
-    method public String? getDataMimeType();
-    method public android.net.Uri? getDataUri();
-    method public android.os.Bundle getExtras();
-    method public androidx.core.app.Person? getPerson();
-    method @Deprecated public CharSequence? getSender();
-    method public CharSequence? getText();
-    method public long getTimestamp();
-    method public androidx.core.app.NotificationCompat.MessagingStyle.Message setData(String?, android.net.Uri?);
-  }
-
-  public abstract static class NotificationCompat.Style {
-    ctor public NotificationCompat.Style();
-    method public android.app.Notification? build();
-    method public void setBuilder(androidx.core.app.NotificationCompat.Builder?);
-  }
-
-  public static final class NotificationCompat.WearableExtender implements androidx.core.app.NotificationCompat.Extender {
-    ctor public NotificationCompat.WearableExtender();
-    ctor public NotificationCompat.WearableExtender(android.app.Notification);
-    method public androidx.core.app.NotificationCompat.WearableExtender addAction(androidx.core.app.NotificationCompat.Action);
-    method public androidx.core.app.NotificationCompat.WearableExtender addActions(java.util.List<androidx.core.app.NotificationCompat.Action!>);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender addPage(android.app.Notification);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender addPages(java.util.List<android.app.Notification!>);
-    method public androidx.core.app.NotificationCompat.WearableExtender clearActions();
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender clearPages();
-    method public androidx.core.app.NotificationCompat.WearableExtender clone();
-    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
-    method public java.util.List<androidx.core.app.NotificationCompat.Action!> getActions();
-    method @Deprecated public android.graphics.Bitmap? getBackground();
-    method public String? getBridgeTag();
-    method public int getContentAction();
-    method @Deprecated public int getContentIcon();
-    method @Deprecated public int getContentIconGravity();
-    method public boolean getContentIntentAvailableOffline();
-    method @Deprecated public int getCustomContentHeight();
-    method @Deprecated public int getCustomSizePreset();
-    method public String? getDismissalId();
-    method @Deprecated public android.app.PendingIntent? getDisplayIntent();
-    method @Deprecated public int getGravity();
-    method @Deprecated public boolean getHintAmbientBigPicture();
-    method @Deprecated public boolean getHintAvoidBackgroundClipping();
-    method public boolean getHintContentIntentLaunchesActivity();
-    method @Deprecated public boolean getHintHideIcon();
-    method @Deprecated public int getHintScreenTimeout();
-    method @Deprecated public boolean getHintShowBackgroundOnly();
-    method @Deprecated public java.util.List<android.app.Notification!> getPages();
-    method public boolean getStartScrollBottom();
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setBackground(android.graphics.Bitmap?);
-    method public androidx.core.app.NotificationCompat.WearableExtender setBridgeTag(String?);
-    method public androidx.core.app.NotificationCompat.WearableExtender setContentAction(int);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setContentIcon(int);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setContentIconGravity(int);
-    method public androidx.core.app.NotificationCompat.WearableExtender setContentIntentAvailableOffline(boolean);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setCustomContentHeight(int);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setCustomSizePreset(int);
-    method public androidx.core.app.NotificationCompat.WearableExtender setDismissalId(String?);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setDisplayIntent(android.app.PendingIntent?);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setGravity(int);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintAmbientBigPicture(boolean);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintAvoidBackgroundClipping(boolean);
-    method public androidx.core.app.NotificationCompat.WearableExtender setHintContentIntentLaunchesActivity(boolean);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintHideIcon(boolean);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintScreenTimeout(int);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintShowBackgroundOnly(boolean);
-    method public androidx.core.app.NotificationCompat.WearableExtender setStartScrollBottom(boolean);
-    field @Deprecated public static final int SCREEN_TIMEOUT_LONG = -1; // 0xffffffff
-    field @Deprecated public static final int SCREEN_TIMEOUT_SHORT = 0; // 0x0
-    field @Deprecated public static final int SIZE_DEFAULT = 0; // 0x0
-    field @Deprecated public static final int SIZE_FULL_SCREEN = 5; // 0x5
-    field @Deprecated public static final int SIZE_LARGE = 4; // 0x4
-    field @Deprecated public static final int SIZE_MEDIUM = 3; // 0x3
-    field @Deprecated public static final int SIZE_SMALL = 2; // 0x2
-    field @Deprecated public static final int SIZE_XSMALL = 1; // 0x1
-    field public static final int UNSET_ACTION_INDEX = -1; // 0xffffffff
-  }
-
-  public final class NotificationCompatExtras {
-    field public static final String EXTRA_ACTION_EXTRAS = "android.support.actionExtras";
-    field public static final String EXTRA_GROUP_KEY = "android.support.groupKey";
-    field public static final String EXTRA_GROUP_SUMMARY = "android.support.isGroupSummary";
-    field public static final String EXTRA_LOCAL_ONLY = "android.support.localOnly";
-    field public static final String EXTRA_REMOTE_INPUTS = "android.support.remoteInputs";
-    field public static final String EXTRA_SORT_KEY = "android.support.sortKey";
-  }
-
-  public abstract class NotificationCompatSideChannelService extends android.app.Service {
-    ctor public NotificationCompatSideChannelService();
-    method public abstract void cancel(String!, int, String!);
-    method public abstract void cancelAll(String!);
-    method public abstract void notify(String!, int, String!, android.app.Notification!);
-    method public android.os.IBinder! onBind(android.content.Intent!);
-  }
-
-  public final class NotificationManagerCompat {
-    method public boolean areNotificationsEnabled();
-    method public void cancel(int);
-    method public void cancel(String?, int);
-    method public void cancelAll();
-    method public void createNotificationChannel(android.app.NotificationChannel);
-    method public void createNotificationChannel(androidx.core.app.NotificationChannelCompat);
-    method public void createNotificationChannelGroup(android.app.NotificationChannelGroup);
-    method public void createNotificationChannelGroup(androidx.core.app.NotificationChannelGroupCompat);
-    method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup!>);
-    method public void createNotificationChannelGroupsCompat(java.util.List<androidx.core.app.NotificationChannelGroupCompat!>);
-    method public void createNotificationChannels(java.util.List<android.app.NotificationChannel!>);
-    method public void createNotificationChannelsCompat(java.util.List<androidx.core.app.NotificationChannelCompat!>);
-    method public void deleteNotificationChannel(String);
-    method public void deleteNotificationChannelGroup(String);
-    method public void deleteUnlistedNotificationChannels(java.util.Collection<java.lang.String!>);
-    method public static androidx.core.app.NotificationManagerCompat from(android.content.Context);
-    method public static java.util.Set<java.lang.String!> getEnabledListenerPackages(android.content.Context);
-    method public int getImportance();
-    method public android.app.NotificationChannel? getNotificationChannel(String);
-    method public android.app.NotificationChannel? getNotificationChannel(String, String);
-    method public androidx.core.app.NotificationChannelCompat? getNotificationChannelCompat(String);
-    method public androidx.core.app.NotificationChannelCompat? getNotificationChannelCompat(String, String);
-    method public android.app.NotificationChannelGroup? getNotificationChannelGroup(String);
-    method public androidx.core.app.NotificationChannelGroupCompat? getNotificationChannelGroupCompat(String);
-    method public java.util.List<android.app.NotificationChannelGroup!> getNotificationChannelGroups();
-    method public java.util.List<androidx.core.app.NotificationChannelGroupCompat!> getNotificationChannelGroupsCompat();
-    method public java.util.List<android.app.NotificationChannel!> getNotificationChannels();
-    method public java.util.List<androidx.core.app.NotificationChannelCompat!> getNotificationChannelsCompat();
-    method public void notify(int, android.app.Notification);
-    method public void notify(String?, int, android.app.Notification);
-    field public static final String ACTION_BIND_SIDE_CHANNEL = "android.support.BIND_NOTIFICATION_SIDE_CHANNEL";
-    field public static final String EXTRA_USE_SIDE_CHANNEL = "android.support.useSideChannel";
-    field public static final int IMPORTANCE_DEFAULT = 3; // 0x3
-    field public static final int IMPORTANCE_HIGH = 4; // 0x4
-    field public static final int IMPORTANCE_LOW = 2; // 0x2
-    field public static final int IMPORTANCE_MAX = 5; // 0x5
-    field public static final int IMPORTANCE_MIN = 1; // 0x1
-    field public static final int IMPORTANCE_NONE = 0; // 0x0
-    field public static final int IMPORTANCE_UNSPECIFIED = -1000; // 0xfffffc18
-  }
-
-  public interface OnMultiWindowModeChangedProvider {
-    method public void addOnMultiWindowModeChangedListener(androidx.core.util.Consumer<androidx.core.app.MultiWindowModeChangedInfo!>);
-    method public void removeOnMultiWindowModeChangedListener(androidx.core.util.Consumer<androidx.core.app.MultiWindowModeChangedInfo!>);
-  }
-
-  public interface OnNewIntentProvider {
-    method public void addOnNewIntentListener(androidx.core.util.Consumer<android.content.Intent!>);
-    method public void removeOnNewIntentListener(androidx.core.util.Consumer<android.content.Intent!>);
-  }
-
-  public interface OnPictureInPictureModeChangedProvider {
-    method public void addOnPictureInPictureModeChangedListener(androidx.core.util.Consumer<androidx.core.app.PictureInPictureModeChangedInfo!>);
-    method public void removeOnPictureInPictureModeChangedListener(androidx.core.util.Consumer<androidx.core.app.PictureInPictureModeChangedInfo!>);
-  }
-
-  public class Person {
-    method public static androidx.core.app.Person fromBundle(android.os.Bundle);
-    method public androidx.core.graphics.drawable.IconCompat? getIcon();
-    method public String? getKey();
-    method public CharSequence? getName();
-    method public String? getUri();
-    method public boolean isBot();
-    method public boolean isImportant();
-    method public androidx.core.app.Person.Builder toBuilder();
-    method public android.os.Bundle toBundle();
-  }
-
-  public static class Person.Builder {
-    ctor public Person.Builder();
-    method public androidx.core.app.Person build();
-    method public androidx.core.app.Person.Builder setBot(boolean);
-    method public androidx.core.app.Person.Builder setIcon(androidx.core.graphics.drawable.IconCompat?);
-    method public androidx.core.app.Person.Builder setImportant(boolean);
-    method public androidx.core.app.Person.Builder setKey(String?);
-    method public androidx.core.app.Person.Builder setName(CharSequence?);
-    method public androidx.core.app.Person.Builder setUri(String?);
-  }
-
-  public final class PictureInPictureModeChangedInfo {
-    ctor public PictureInPictureModeChangedInfo(boolean);
-    ctor @RequiresApi(26) public PictureInPictureModeChangedInfo(boolean, android.content.res.Configuration);
-    method @RequiresApi(26) public android.content.res.Configuration getNewConfig();
-    method public boolean isInPictureInPictureMode();
-  }
-
-  public final class RemoteActionCompat implements androidx.versionedparcelable.VersionedParcelable {
-    ctor public RemoteActionCompat(androidx.core.graphics.drawable.IconCompat, CharSequence, CharSequence, android.app.PendingIntent);
-    ctor public RemoteActionCompat(androidx.core.app.RemoteActionCompat);
-    method @RequiresApi(26) public static androidx.core.app.RemoteActionCompat createFromRemoteAction(android.app.RemoteAction);
-    method public android.app.PendingIntent getActionIntent();
-    method public CharSequence getContentDescription();
-    method public androidx.core.graphics.drawable.IconCompat getIcon();
-    method public CharSequence getTitle();
-    method public boolean isEnabled();
-    method public void setEnabled(boolean);
-    method public void setShouldShowIcon(boolean);
-    method public boolean shouldShowIcon();
-    method @RequiresApi(26) public android.app.RemoteAction toRemoteAction();
-  }
-
-  public final class RemoteInput {
-    method public static void addDataResultToIntent(androidx.core.app.RemoteInput, android.content.Intent, java.util.Map<java.lang.String!,android.net.Uri!>);
-    method public static void addResultsToIntent(androidx.core.app.RemoteInput![], android.content.Intent, android.os.Bundle);
-    method public boolean getAllowFreeFormInput();
-    method public java.util.Set<java.lang.String!>? getAllowedDataTypes();
-    method public CharSequence![]? getChoices();
-    method public static java.util.Map<java.lang.String!,android.net.Uri!>? getDataResultsFromIntent(android.content.Intent, String);
-    method public int getEditChoicesBeforeSending();
-    method public android.os.Bundle getExtras();
-    method public CharSequence? getLabel();
-    method public String getResultKey();
-    method public static android.os.Bundle? getResultsFromIntent(android.content.Intent);
-    method public static int getResultsSource(android.content.Intent);
-    method public boolean isDataOnly();
-    method public static void setResultsSource(android.content.Intent, int);
-    field public static final int EDIT_CHOICES_BEFORE_SENDING_AUTO = 0; // 0x0
-    field public static final int EDIT_CHOICES_BEFORE_SENDING_DISABLED = 1; // 0x1
-    field public static final int EDIT_CHOICES_BEFORE_SENDING_ENABLED = 2; // 0x2
-    field public static final String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
-    field public static final String RESULTS_CLIP_LABEL = "android.remoteinput.results";
-    field public static final int SOURCE_CHOICE = 1; // 0x1
-    field public static final int SOURCE_FREE_FORM_INPUT = 0; // 0x0
-  }
-
-  public static final class RemoteInput.Builder {
-    ctor public RemoteInput.Builder(String);
-    method public androidx.core.app.RemoteInput.Builder addExtras(android.os.Bundle);
-    method public androidx.core.app.RemoteInput build();
-    method public android.os.Bundle getExtras();
-    method public androidx.core.app.RemoteInput.Builder setAllowDataType(String, boolean);
-    method public androidx.core.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
-    method public androidx.core.app.RemoteInput.Builder setChoices(CharSequence![]?);
-    method public androidx.core.app.RemoteInput.Builder setEditChoicesBeforeSending(int);
-    method public androidx.core.app.RemoteInput.Builder setLabel(CharSequence?);
-  }
-
-  public final class ServiceCompat {
-    method public static void stopForeground(android.app.Service, int);
-    field public static final int START_STICKY = 1; // 0x1
-    field public static final int STOP_FOREGROUND_DETACH = 2; // 0x2
-    field public static final int STOP_FOREGROUND_REMOVE = 1; // 0x1
-  }
-
-  public final class ShareCompat {
-    method @Deprecated public static void configureMenuItem(android.view.MenuItem, androidx.core.app.ShareCompat.IntentBuilder);
-    method @Deprecated public static void configureMenuItem(android.view.Menu, @IdRes int, androidx.core.app.ShareCompat.IntentBuilder);
-    method public static android.content.ComponentName? getCallingActivity(android.app.Activity);
-    method public static String? getCallingPackage(android.app.Activity);
-    field public static final String EXTRA_CALLING_ACTIVITY = "androidx.core.app.EXTRA_CALLING_ACTIVITY";
-    field public static final String EXTRA_CALLING_ACTIVITY_INTEROP = "android.support.v4.app.EXTRA_CALLING_ACTIVITY";
-    field public static final String EXTRA_CALLING_PACKAGE = "androidx.core.app.EXTRA_CALLING_PACKAGE";
-    field public static final String EXTRA_CALLING_PACKAGE_INTEROP = "android.support.v4.app.EXTRA_CALLING_PACKAGE";
-  }
-
-  public static class ShareCompat.IntentBuilder {
-    ctor public ShareCompat.IntentBuilder(android.content.Context);
-    method public androidx.core.app.ShareCompat.IntentBuilder addEmailBcc(String);
-    method public androidx.core.app.ShareCompat.IntentBuilder addEmailBcc(String![]);
-    method public androidx.core.app.ShareCompat.IntentBuilder addEmailCc(String);
-    method public androidx.core.app.ShareCompat.IntentBuilder addEmailCc(String![]);
-    method public androidx.core.app.ShareCompat.IntentBuilder addEmailTo(String);
-    method public androidx.core.app.ShareCompat.IntentBuilder addEmailTo(String![]);
-    method public androidx.core.app.ShareCompat.IntentBuilder addStream(android.net.Uri);
-    method public android.content.Intent createChooserIntent();
-    method @Deprecated public static androidx.core.app.ShareCompat.IntentBuilder from(android.app.Activity);
-    method public android.content.Intent getIntent();
-    method public androidx.core.app.ShareCompat.IntentBuilder setChooserTitle(CharSequence?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setChooserTitle(@StringRes int);
-    method public androidx.core.app.ShareCompat.IntentBuilder setEmailBcc(String![]?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setEmailCc(String![]?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setEmailTo(String![]?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setHtmlText(String?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setStream(android.net.Uri?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setSubject(String?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setText(CharSequence?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setType(String?);
-    method public void startChooser();
-  }
-
-  public static class ShareCompat.IntentReader {
-    ctor public ShareCompat.IntentReader(android.app.Activity);
-    ctor public ShareCompat.IntentReader(android.content.Context, android.content.Intent);
-    method @Deprecated public static androidx.core.app.ShareCompat.IntentReader from(android.app.Activity);
-    method public android.content.ComponentName? getCallingActivity();
-    method public android.graphics.drawable.Drawable? getCallingActivityIcon();
-    method public android.graphics.drawable.Drawable? getCallingApplicationIcon();
-    method public CharSequence? getCallingApplicationLabel();
-    method public String? getCallingPackage();
-    method public String![]? getEmailBcc();
-    method public String![]? getEmailCc();
-    method public String![]? getEmailTo();
-    method public String? getHtmlText();
-    method public android.net.Uri? getStream();
-    method public android.net.Uri? getStream(int);
-    method public int getStreamCount();
-    method public String? getSubject();
-    method public CharSequence? getText();
-    method public String? getType();
-    method public boolean isMultipleShare();
-    method public boolean isShareIntent();
-    method public boolean isSingleShare();
-  }
-
-  public abstract class SharedElementCallback {
-    ctor public SharedElementCallback();
-    method public android.os.Parcelable! onCaptureSharedElementSnapshot(android.view.View!, android.graphics.Matrix!, android.graphics.RectF!);
-    method public android.view.View! onCreateSnapshotView(android.content.Context!, android.os.Parcelable!);
-    method public void onMapSharedElements(java.util.List<java.lang.String!>!, java.util.Map<java.lang.String!,android.view.View!>!);
-    method public void onRejectSharedElements(java.util.List<android.view.View!>!);
-    method public void onSharedElementEnd(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, java.util.List<android.view.View!>!);
-    method public void onSharedElementStart(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, java.util.List<android.view.View!>!);
-    method public void onSharedElementsArrived(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, androidx.core.app.SharedElementCallback.OnSharedElementsReadyListener!);
-  }
-
-  public static interface SharedElementCallback.OnSharedElementsReadyListener {
-    method public void onSharedElementsReady();
-  }
-
-  public final class TaskStackBuilder implements java.lang.Iterable<android.content.Intent> {
-    method public androidx.core.app.TaskStackBuilder addNextIntent(android.content.Intent);
-    method public androidx.core.app.TaskStackBuilder addNextIntentWithParentStack(android.content.Intent);
-    method public androidx.core.app.TaskStackBuilder addParentStack(android.app.Activity);
-    method public androidx.core.app.TaskStackBuilder addParentStack(Class<?>);
-    method public androidx.core.app.TaskStackBuilder addParentStack(android.content.ComponentName);
-    method public static androidx.core.app.TaskStackBuilder create(android.content.Context);
-    method public android.content.Intent? editIntentAt(int);
-    method @Deprecated public static androidx.core.app.TaskStackBuilder! from(android.content.Context!);
-    method @Deprecated public android.content.Intent! getIntent(int);
-    method public int getIntentCount();
-    method public android.content.Intent![] getIntents();
-    method public android.app.PendingIntent? getPendingIntent(int, int);
-    method public android.app.PendingIntent? getPendingIntent(int, int, android.os.Bundle?);
-    method @Deprecated public java.util.Iterator<android.content.Intent!> iterator();
-    method public void startActivities();
-    method public void startActivities(android.os.Bundle?);
-  }
-
-  public static interface TaskStackBuilder.SupportParentable {
-    method public android.content.Intent? getSupportParentActivityIntent();
-  }
-
-}
-
-package androidx.core.content {
-
-  public final class ContentProviderCompat {
-    method public static android.content.Context requireContext(android.content.ContentProvider);
-  }
-
-  public final class ContentResolverCompat {
-    method public static android.database.Cursor? query(android.content.ContentResolver, android.net.Uri, String![]?, String?, String![]?, String?, androidx.core.os.CancellationSignal?);
-  }
-
-  public class ContextCompat {
-    ctor protected ContextCompat();
-    method public static int checkSelfPermission(android.content.Context, String);
-    method public static android.content.Context? createDeviceProtectedStorageContext(android.content.Context);
-    method public static String? getAttributionTag(android.content.Context);
-    method public static java.io.File getCodeCacheDir(android.content.Context);
-    method @ColorInt public static int getColor(android.content.Context, @ColorRes int);
-    method public static android.content.res.ColorStateList? getColorStateList(android.content.Context, @ColorRes int);
-    method public static java.io.File? getDataDir(android.content.Context);
-    method public static android.graphics.drawable.Drawable? getDrawable(android.content.Context, @DrawableRes int);
-    method public static java.io.File![] getExternalCacheDirs(android.content.Context);
-    method public static java.io.File![] getExternalFilesDirs(android.content.Context, String?);
-    method public static java.util.concurrent.Executor getMainExecutor(android.content.Context);
-    method public static java.io.File? getNoBackupFilesDir(android.content.Context);
-    method public static java.io.File![] getObbDirs(android.content.Context);
-    method public static <T> T? getSystemService(android.content.Context, Class<T!>);
-    method public static String? getSystemServiceName(android.content.Context, Class<?>);
-    method public static boolean isDeviceProtectedStorage(android.content.Context);
-    method public static boolean startActivities(android.content.Context, android.content.Intent![]);
-    method public static boolean startActivities(android.content.Context, android.content.Intent![], android.os.Bundle?);
-    method public static void startActivity(android.content.Context, android.content.Intent, android.os.Bundle?);
-    method public static void startForegroundService(android.content.Context, android.content.Intent);
-  }
-
-  public class FileProvider extends android.content.ContentProvider {
-    ctor public FileProvider();
-    ctor protected FileProvider(@XmlRes int);
-    method public int delete(android.net.Uri, String?, String![]?);
-    method public String? getType(android.net.Uri);
-    method public static android.net.Uri! getUriForFile(android.content.Context, String, java.io.File);
-    method public static android.net.Uri getUriForFile(android.content.Context, String, java.io.File, String);
-    method public android.net.Uri! insert(android.net.Uri, android.content.ContentValues);
-    method public boolean onCreate();
-    method public android.database.Cursor query(android.net.Uri, String![]?, String?, String![]?, String?);
-    method public int update(android.net.Uri, android.content.ContentValues, String?, String![]?);
-  }
-
-  public final class IntentCompat {
-    method public static android.content.Intent createManageUnusedAppRestrictionsIntent(android.content.Context, String);
-    method public static android.content.Intent makeMainSelectorActivity(String, String);
-    field public static final String ACTION_CREATE_REMINDER = "android.intent.action.CREATE_REMINDER";
-    field public static final String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
-    field public static final String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
-    field public static final String EXTRA_START_PLAYBACK = "android.intent.extra.START_PLAYBACK";
-    field public static final String EXTRA_TIME = "android.intent.extra.TIME";
-  }
-
-  public final class LocusIdCompat {
-    ctor public LocusIdCompat(String);
-    method public String getId();
-    method @RequiresApi(29) public android.content.LocusId toLocusId();
-    method @RequiresApi(29) public static androidx.core.content.LocusIdCompat toLocusIdCompat(android.content.LocusId);
-  }
-
-  public final class MimeTypeFilter {
-    method public static boolean matches(String?, String);
-    method public static String? matches(String?, String![]);
-    method public static String? matches(String![]?, String);
-    method public static String![] matchesMany(String![]?, String);
-  }
-
-  public interface OnConfigurationChangedProvider {
-    method public void addOnConfigurationChangedListener(androidx.core.util.Consumer<android.content.res.Configuration!>);
-    method public void removeOnConfigurationChangedListener(androidx.core.util.Consumer<android.content.res.Configuration!>);
-  }
-
-  public interface OnTrimMemoryProvider {
-    method public void addOnTrimMemoryListener(androidx.core.util.Consumer<java.lang.Integer!>);
-    method public void removeOnTrimMemoryListener(androidx.core.util.Consumer<java.lang.Integer!>);
-  }
-
-  public final class PackageManagerCompat {
-    method public static com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> getUnusedAppRestrictionsStatus(android.content.Context);
-    field public static final String ACTION_PERMISSION_REVOCATION_SETTINGS = "android.intent.action.AUTO_REVOKE_PERMISSIONS";
-  }
-
-  public final class PermissionChecker {
-    method public static int checkCallingOrSelfPermission(android.content.Context, String);
-    method public static int checkCallingPermission(android.content.Context, String, String?);
-    method public static int checkPermission(android.content.Context, String, int, int, String?);
-    method public static int checkSelfPermission(android.content.Context, String);
-    field public static final int PERMISSION_DENIED = -1; // 0xffffffff
-    field public static final int PERMISSION_DENIED_APP_OP = -2; // 0xfffffffe
-    field public static final int PERMISSION_GRANTED = 0; // 0x0
-  }
-
-  @Deprecated public final class SharedPreferencesCompat {
-  }
-
-  @Deprecated public static final class SharedPreferencesCompat.EditorCompat {
-    method @Deprecated public void apply(android.content.SharedPreferences.Editor);
-    method @Deprecated public static androidx.core.content.SharedPreferencesCompat.EditorCompat! getInstance();
-  }
-
-  public class UnusedAppRestrictionsBackportCallback {
-    method public void onResult(boolean, boolean) throws android.os.RemoteException;
-  }
-
-  public abstract class UnusedAppRestrictionsBackportService extends android.app.Service {
-    ctor public UnusedAppRestrictionsBackportService();
-    method protected abstract void isPermissionRevocationEnabled(androidx.core.content.UnusedAppRestrictionsBackportCallback);
-    method public android.os.IBinder? onBind(android.content.Intent?);
-    field public static final String ACTION_UNUSED_APP_RESTRICTIONS_BACKPORT_CONNECTION = "android.support.unusedapprestrictions.action.CustomUnusedAppRestrictionsBackportService";
-  }
-
-  public final class UnusedAppRestrictionsConstants {
-    field public static final int API_30 = 4; // 0x4
-    field public static final int API_30_BACKPORT = 3; // 0x3
-    field public static final int API_31 = 5; // 0x5
-    field public static final int DISABLED = 2; // 0x2
-    field public static final int ERROR = 0; // 0x0
-    field public static final int FEATURE_NOT_AVAILABLE = 1; // 0x1
-  }
-
-}
-
-package androidx.core.content.pm {
-
-  @Deprecated public final class ActivityInfoCompat {
-    field @Deprecated public static final int CONFIG_UI_MODE = 512; // 0x200
-  }
-
-  public final class PackageInfoCompat {
-    method public static long getLongVersionCode(android.content.pm.PackageInfo);
-    method public static java.util.List<android.content.pm.Signature!> getSignatures(android.content.pm.PackageManager, String) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public static boolean hasSignatures(android.content.pm.PackageManager, String, @Size(min=1) java.util.Map<byte[]!,java.lang.Integer!>, boolean) throws android.content.pm.PackageManager.NameNotFoundException;
-  }
-
-  public final class PermissionInfoCompat {
-    method public static int getProtection(android.content.pm.PermissionInfo);
-    method public static int getProtectionFlags(android.content.pm.PermissionInfo);
-  }
-
-  public class ShortcutInfoCompat {
-    method public android.content.ComponentName? getActivity();
-    method public java.util.Set<java.lang.String!>? getCategories();
-    method public CharSequence? getDisabledMessage();
-    method public int getDisabledReason();
-    method public int getExcludedFromSurfaces();
-    method public android.os.PersistableBundle? getExtras();
-    method public String getId();
-    method public android.content.Intent getIntent();
-    method public android.content.Intent![] getIntents();
-    method public long getLastChangedTimestamp();
-    method public androidx.core.content.LocusIdCompat? getLocusId();
-    method public CharSequence? getLongLabel();
-    method public String getPackage();
-    method public int getRank();
-    method public CharSequence getShortLabel();
-    method public android.os.UserHandle? getUserHandle();
-    method public boolean hasKeyFieldsOnly();
-    method public boolean isCached();
-    method public boolean isDeclaredInManifest();
-    method public boolean isDynamic();
-    method public boolean isEnabled();
-    method public boolean isExcludedFromSurfaces(int);
-    method public boolean isImmutable();
-    method public boolean isPinned();
-    method @RequiresApi(25) public android.content.pm.ShortcutInfo! toShortcutInfo();
-    field public static final int SURFACE_LAUNCHER = 1; // 0x1
-  }
-
-  public static class ShortcutInfoCompat.Builder {
-    ctor public ShortcutInfoCompat.Builder(android.content.Context, String);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder addCapabilityBinding(String);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder addCapabilityBinding(String, String, java.util.List<java.lang.String!>);
-    method public androidx.core.content.pm.ShortcutInfoCompat build();
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setActivity(android.content.ComponentName);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setAlwaysBadged();
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setCategories(java.util.Set<java.lang.String!>);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setDisabledMessage(CharSequence);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setExcludedFromSurfaces(int);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setExtras(android.os.PersistableBundle);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIcon(androidx.core.graphics.drawable.IconCompat!);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIntent(android.content.Intent);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIntents(android.content.Intent![]);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIsConversation();
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLocusId(androidx.core.content.LocusIdCompat?);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLabel(CharSequence);
-    method @Deprecated public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived();
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived(boolean);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setPerson(androidx.core.app.Person);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setPersons(androidx.core.app.Person![]);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setRank(int);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setShortLabel(CharSequence);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setSliceUri(android.net.Uri);
-  }
-
-  public class ShortcutManagerCompat {
-    method public static boolean addDynamicShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
-    method public static android.content.Intent createShortcutResultIntent(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat);
-    method public static void disableShortcuts(android.content.Context, java.util.List<java.lang.String!>, CharSequence?);
-    method public static void enableShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
-    method public static java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getDynamicShortcuts(android.content.Context);
-    method public static int getIconMaxHeight(android.content.Context);
-    method public static int getIconMaxWidth(android.content.Context);
-    method public static int getMaxShortcutCountPerActivity(android.content.Context);
-    method public static java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getShortcuts(android.content.Context, int);
-    method public static boolean isRateLimitingActive(android.content.Context);
-    method public static boolean isRequestPinShortcutSupported(android.content.Context);
-    method public static boolean pushDynamicShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat);
-    method public static void removeAllDynamicShortcuts(android.content.Context);
-    method public static void removeDynamicShortcuts(android.content.Context, java.util.List<java.lang.String!>);
-    method public static void removeLongLivedShortcuts(android.content.Context, java.util.List<java.lang.String!>);
-    method public static void reportShortcutUsed(android.content.Context, String);
-    method public static boolean requestPinShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat, android.content.IntentSender?);
-    method public static boolean setDynamicShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
-    method public static boolean updateShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
-    field public static final String EXTRA_SHORTCUT_ID = "android.intent.extra.shortcut.ID";
-    field public static final int FLAG_MATCH_CACHED = 8; // 0x8
-    field public static final int FLAG_MATCH_DYNAMIC = 2; // 0x2
-    field public static final int FLAG_MATCH_MANIFEST = 1; // 0x1
-    field public static final int FLAG_MATCH_PINNED = 4; // 0x4
-  }
-
-}
-
-package androidx.core.content.res {
-
-  public final class ConfigurationHelper {
-    method public static int getDensityDpi(android.content.res.Resources);
-  }
-
-  public final class ResourcesCompat {
-    method public static void clearCachesForTheme(android.content.res.Resources.Theme);
-    method public static android.graphics.Typeface? getCachedFont(android.content.Context, @FontRes int) throws android.content.res.Resources.NotFoundException;
-    method @ColorInt public static int getColor(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
-    method public static android.content.res.ColorStateList? getColorStateList(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
-    method public static android.graphics.drawable.Drawable? getDrawable(android.content.res.Resources, @DrawableRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
-    method public static android.graphics.drawable.Drawable? getDrawableForDensity(android.content.res.Resources, @DrawableRes int, int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
-    method public static float getFloat(android.content.res.Resources, @DimenRes int);
-    method public static android.graphics.Typeface? getFont(android.content.Context, @FontRes int) throws android.content.res.Resources.NotFoundException;
-    method public static void getFont(android.content.Context, @FontRes int, androidx.core.content.res.ResourcesCompat.FontCallback, android.os.Handler?) throws android.content.res.Resources.NotFoundException;
-    field @AnyRes public static final int ID_NULL = 0; // 0x0
-  }
-
-  public abstract static class ResourcesCompat.FontCallback {
-    ctor public ResourcesCompat.FontCallback();
-    method public abstract void onFontRetrievalFailed(int);
-    method public abstract void onFontRetrieved(android.graphics.Typeface);
-  }
-
-  public static final class ResourcesCompat.ThemeCompat {
-    method public static void rebase(android.content.res.Resources.Theme);
-  }
-
-}
-
-package androidx.core.database {
-
-  public final class CursorWindowCompat {
-    method public static android.database.CursorWindow create(String?, long);
-  }
-
-  @Deprecated public final class DatabaseUtilsCompat {
-    method @Deprecated public static String![]! appendSelectionArgs(String![]!, String![]!);
-    method @Deprecated public static String! concatenateWhere(String!, String!);
-  }
-
-}
-
-package androidx.core.database.sqlite {
-
-  public final class SQLiteCursorCompat {
-    method public static void setFillWindowForwardOnly(android.database.sqlite.SQLiteCursor, boolean);
-  }
-
-}
-
-package androidx.core.graphics {
-
-  public final class BitmapCompat {
-    method public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap, int, int, android.graphics.Rect?, boolean);
-    method public static int getAllocationByteCount(android.graphics.Bitmap);
-    method public static boolean hasMipMap(android.graphics.Bitmap);
-    method public static void setHasMipMap(android.graphics.Bitmap, boolean);
-  }
-
-  public class BlendModeColorFilterCompat {
-    method public static android.graphics.ColorFilter? createBlendModeColorFilterCompat(int, androidx.core.graphics.BlendModeCompat);
-  }
-
-  public enum BlendModeCompat {
-    enum_constant public static final androidx.core.graphics.BlendModeCompat CLEAR;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR_BURN;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR_DODGE;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat DARKEN;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat DIFFERENCE;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat DST;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_ATOP;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_IN;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OUT;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OVER;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat EXCLUSION;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat HARD_LIGHT;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat HUE;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat LIGHTEN;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat LUMINOSITY;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat MODULATE;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat MULTIPLY;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat OVERLAY;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat PLUS;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat SATURATION;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat SCREEN;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat SOFT_LIGHT;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_ATOP;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_IN;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OUT;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OVER;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat XOR;
-  }
-
-  public final class ColorUtils {
-    method @ColorInt public static int HSLToColor(float[]);
-    method @ColorInt public static int LABToColor(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double);
-    method public static void LABToXYZ(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double, double[]);
-    method public static void RGBToHSL(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, float[]);
-    method public static void RGBToLAB(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, double[]);
-    method public static void RGBToXYZ(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, double[]);
-    method @ColorInt public static int XYZToColor(@FloatRange(from=0.0f, to=95.047) double, @FloatRange(from=0.0f, to=0x64) double, @FloatRange(from=0.0f, to=108.883) double);
-    method public static void XYZToLAB(@FloatRange(from=0.0f, to=95.047) double, @FloatRange(from=0.0f, to=0x64) double, @FloatRange(from=0.0f, to=108.883) double, double[]);
-    method @ColorInt public static int blendARGB(@ColorInt int, @ColorInt int, @FloatRange(from=0.0, to=1.0) float);
-    method public static void blendHSL(float[], float[], @FloatRange(from=0.0, to=1.0) float, float[]);
-    method public static void blendLAB(double[], double[], @FloatRange(from=0.0, to=1.0) double, double[]);
-    method public static double calculateContrast(@ColorInt int, @ColorInt int);
-    method @FloatRange(from=0.0, to=1.0) public static double calculateLuminance(@ColorInt int);
-    method public static int calculateMinimumAlpha(@ColorInt int, @ColorInt int, float);
-    method public static void colorToHSL(@ColorInt int, float[]);
-    method public static void colorToLAB(@ColorInt int, double[]);
-    method public static void colorToXYZ(@ColorInt int, double[]);
-    method public static int compositeColors(@ColorInt int, @ColorInt int);
-    method @RequiresApi(26) public static android.graphics.Color compositeColors(android.graphics.Color, android.graphics.Color);
-    method public static double distanceEuclidean(double[], double[]);
-    method @ColorInt public static int setAlphaComponent(@ColorInt int, @IntRange(from=0, to=255) int);
-  }
-
-  public final class Insets {
-    method public static androidx.core.graphics.Insets add(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
-    method public static androidx.core.graphics.Insets max(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
-    method public static androidx.core.graphics.Insets min(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
-    method public static androidx.core.graphics.Insets of(int, int, int, int);
-    method public static androidx.core.graphics.Insets of(android.graphics.Rect);
-    method public static androidx.core.graphics.Insets subtract(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
-    method @RequiresApi(api=29) public static androidx.core.graphics.Insets toCompatInsets(android.graphics.Insets);
-    method @RequiresApi(29) public android.graphics.Insets toPlatformInsets();
-    field public static final androidx.core.graphics.Insets NONE;
-    field public final int bottom;
-    field public final int left;
-    field public final int right;
-    field public final int top;
-  }
-
-  public final class PaintCompat {
-    method public static boolean hasGlyph(android.graphics.Paint, String);
-    method public static boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat?);
-  }
-
-  public final class PathSegment {
-    ctor public PathSegment(android.graphics.PointF, float, android.graphics.PointF, float);
-    method public android.graphics.PointF getEnd();
-    method public float getEndFraction();
-    method public android.graphics.PointF getStart();
-    method public float getStartFraction();
-  }
-
-  public final class PathUtils {
-    method @RequiresApi(26) public static java.util.Collection<androidx.core.graphics.PathSegment!> flatten(android.graphics.Path);
-    method @RequiresApi(26) public static java.util.Collection<androidx.core.graphics.PathSegment!> flatten(android.graphics.Path, @FloatRange(from=0) float);
-  }
-
-  public class TypefaceCompat {
-    method public static android.graphics.Typeface create(android.content.Context, android.graphics.Typeface?, int);
-  }
-
-}
-
-package androidx.core.graphics.drawable {
-
-  public final class DrawableCompat {
-    method public static void applyTheme(android.graphics.drawable.Drawable, android.content.res.Resources.Theme);
-    method public static boolean canApplyTheme(android.graphics.drawable.Drawable);
-    method public static void clearColorFilter(android.graphics.drawable.Drawable);
-    method public static int getAlpha(android.graphics.drawable.Drawable);
-    method public static android.graphics.ColorFilter? getColorFilter(android.graphics.drawable.Drawable);
-    method public static int getLayoutDirection(android.graphics.drawable.Drawable);
-    method public static void inflate(android.graphics.drawable.Drawable, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static boolean isAutoMirrored(android.graphics.drawable.Drawable);
-    method @Deprecated public static void jumpToCurrentState(android.graphics.drawable.Drawable);
-    method public static void setAutoMirrored(android.graphics.drawable.Drawable, boolean);
-    method public static void setHotspot(android.graphics.drawable.Drawable, float, float);
-    method public static void setHotspotBounds(android.graphics.drawable.Drawable, int, int, int, int);
-    method public static boolean setLayoutDirection(android.graphics.drawable.Drawable, int);
-    method public static void setTint(android.graphics.drawable.Drawable, @ColorInt int);
-    method public static void setTintList(android.graphics.drawable.Drawable, android.content.res.ColorStateList?);
-    method public static void setTintMode(android.graphics.drawable.Drawable, android.graphics.PorterDuff.Mode);
-    method public static <T extends android.graphics.drawable.Drawable> T! unwrap(android.graphics.drawable.Drawable);
-    method public static android.graphics.drawable.Drawable wrap(android.graphics.drawable.Drawable);
-  }
-
-  public class IconCompat implements androidx.versionedparcelable.VersionedParcelable {
-    method public static androidx.core.graphics.drawable.IconCompat? createFromBundle(android.os.Bundle);
-    method @RequiresApi(23) public static androidx.core.graphics.drawable.IconCompat? createFromIcon(android.content.Context, android.graphics.drawable.Icon);
-    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmap(android.graphics.Bitmap);
-    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmapContentUri(String);
-    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmapContentUri(android.net.Uri);
-    method public static androidx.core.graphics.drawable.IconCompat createWithBitmap(android.graphics.Bitmap);
-    method public static androidx.core.graphics.drawable.IconCompat createWithContentUri(String);
-    method public static androidx.core.graphics.drawable.IconCompat createWithContentUri(android.net.Uri);
-    method public static androidx.core.graphics.drawable.IconCompat createWithData(byte[], int, int);
-    method public static androidx.core.graphics.drawable.IconCompat createWithResource(android.content.Context, @DrawableRes int);
-    method @DrawableRes public int getResId();
-    method public String getResPackage();
-    method public int getType();
-    method public android.net.Uri getUri();
-    method public android.graphics.drawable.Drawable? loadDrawable(android.content.Context);
-    method public void onPostParceling();
-    method public void onPreParceling(boolean);
-    method public androidx.core.graphics.drawable.IconCompat setTint(@ColorInt int);
-    method public androidx.core.graphics.drawable.IconCompat setTintList(android.content.res.ColorStateList?);
-    method public androidx.core.graphics.drawable.IconCompat setTintMode(android.graphics.PorterDuff.Mode?);
-    method public android.os.Bundle toBundle();
-    method @Deprecated @RequiresApi(23) public android.graphics.drawable.Icon toIcon();
-    method @RequiresApi(23) public android.graphics.drawable.Icon toIcon(android.content.Context?);
-    field public static final int TYPE_ADAPTIVE_BITMAP = 5; // 0x5
-    field public static final int TYPE_BITMAP = 1; // 0x1
-    field public static final int TYPE_DATA = 3; // 0x3
-    field public static final int TYPE_RESOURCE = 2; // 0x2
-    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
-    field public static final int TYPE_URI = 4; // 0x4
-    field public static final int TYPE_URI_ADAPTIVE_BITMAP = 6; // 0x6
-  }
-
-  public abstract class RoundedBitmapDrawable extends android.graphics.drawable.Drawable {
-    method public void draw(android.graphics.Canvas);
-    method public final android.graphics.Bitmap? getBitmap();
-    method public float getCornerRadius();
-    method public int getGravity();
-    method public int getOpacity();
-    method public final android.graphics.Paint getPaint();
-    method public boolean hasAntiAlias();
-    method public boolean hasMipMap();
-    method public boolean isCircular();
-    method public void setAlpha(int);
-    method public void setAntiAlias(boolean);
-    method public void setCircular(boolean);
-    method public void setColorFilter(android.graphics.ColorFilter!);
-    method public void setCornerRadius(float);
-    method public void setDither(boolean);
-    method public void setGravity(int);
-    method public void setMipMap(boolean);
-    method public void setTargetDensity(android.graphics.Canvas);
-    method public void setTargetDensity(android.util.DisplayMetrics);
-    method public void setTargetDensity(int);
-  }
-
-  public final class RoundedBitmapDrawableFactory {
-    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, android.graphics.Bitmap?);
-    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, String);
-    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, java.io.InputStream);
-  }
-
-}
-
-package androidx.core.hardware.display {
-
-  public final class DisplayManagerCompat {
-    method public android.view.Display? getDisplay(int);
-    method public android.view.Display![] getDisplays();
-    method public android.view.Display![] getDisplays(String?);
-    method public static androidx.core.hardware.display.DisplayManagerCompat getInstance(android.content.Context);
-    field public static final String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
-  }
-
-}
-
-package androidx.core.hardware.fingerprint {
-
-  @Deprecated public class FingerprintManagerCompat {
-    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public void authenticate(androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject?, int, androidx.core.os.CancellationSignal?, androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationCallback, android.os.Handler?);
-    method @Deprecated public static androidx.core.hardware.fingerprint.FingerprintManagerCompat from(android.content.Context);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean hasEnrolledFingerprints();
-    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean isHardwareDetected();
-  }
-
-  @Deprecated public abstract static class FingerprintManagerCompat.AuthenticationCallback {
-    ctor @Deprecated public FingerprintManagerCompat.AuthenticationCallback();
-    method @Deprecated public void onAuthenticationError(int, CharSequence!);
-    method @Deprecated public void onAuthenticationFailed();
-    method @Deprecated public void onAuthenticationHelp(int, CharSequence!);
-    method @Deprecated public void onAuthenticationSucceeded(androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationResult!);
-  }
-
-  @Deprecated public static final class FingerprintManagerCompat.AuthenticationResult {
-    ctor @Deprecated public FingerprintManagerCompat.AuthenticationResult(androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject!);
-    method @Deprecated public androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject! getCryptoObject();
-  }
-
-  @Deprecated public static class FingerprintManagerCompat.CryptoObject {
-    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(java.security.Signature);
-    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(javax.crypto.Cipher);
-    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(javax.crypto.Mac);
-    method @Deprecated public javax.crypto.Cipher? getCipher();
-    method @Deprecated public javax.crypto.Mac? getMac();
-    method @Deprecated public java.security.Signature? getSignature();
-  }
-
-}
-
-package androidx.core.location {
-
-  public abstract class GnssStatusCompat {
-    method @FloatRange(from=0, to=360) public abstract float getAzimuthDegrees(@IntRange(from=0) int);
-    method @FloatRange(from=0, to=63) public abstract float getBasebandCn0DbHz(@IntRange(from=0) int);
-    method @FloatRange(from=0) public abstract float getCarrierFrequencyHz(@IntRange(from=0) int);
-    method @FloatRange(from=0, to=63) public abstract float getCn0DbHz(@IntRange(from=0) int);
-    method public abstract int getConstellationType(@IntRange(from=0) int);
-    method @FloatRange(from=0xffffffa6, to=90) public abstract float getElevationDegrees(@IntRange(from=0) int);
-    method @IntRange(from=0) public abstract int getSatelliteCount();
-    method @IntRange(from=1, to=200) public abstract int getSvid(@IntRange(from=0) int);
-    method public abstract boolean hasAlmanacData(@IntRange(from=0) int);
-    method public abstract boolean hasBasebandCn0DbHz(@IntRange(from=0) int);
-    method public abstract boolean hasCarrierFrequencyHz(@IntRange(from=0) int);
-    method public abstract boolean hasEphemerisData(@IntRange(from=0) int);
-    method public abstract boolean usedInFix(@IntRange(from=0) int);
-    method @RequiresApi(android.os.Build.VERSION_CODES.N) public static androidx.core.location.GnssStatusCompat wrap(android.location.GnssStatus);
-    method public static androidx.core.location.GnssStatusCompat wrap(android.location.GpsStatus);
-    field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
-    field public static final int CONSTELLATION_GALILEO = 6; // 0x6
-    field public static final int CONSTELLATION_GLONASS = 3; // 0x3
-    field public static final int CONSTELLATION_GPS = 1; // 0x1
-    field public static final int CONSTELLATION_IRNSS = 7; // 0x7
-    field public static final int CONSTELLATION_QZSS = 4; // 0x4
-    field public static final int CONSTELLATION_SBAS = 2; // 0x2
-    field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
-  }
-
-  public abstract static class GnssStatusCompat.Callback {
-    ctor public GnssStatusCompat.Callback();
-    method public void onFirstFix(@IntRange(from=0) int);
-    method public void onSatelliteStatusChanged(androidx.core.location.GnssStatusCompat);
-    method public void onStarted();
-    method public void onStopped();
-  }
-
-  public final class LocationCompat {
-    method public static float getBearingAccuracyDegrees(android.location.Location);
-    method public static long getElapsedRealtimeMillis(android.location.Location);
-    method public static long getElapsedRealtimeNanos(android.location.Location);
-    method public static float getSpeedAccuracyMetersPerSecond(android.location.Location);
-    method public static float getVerticalAccuracyMeters(android.location.Location);
-    method public static boolean hasBearingAccuracy(android.location.Location);
-    method public static boolean hasSpeedAccuracy(android.location.Location);
-    method public static boolean hasVerticalAccuracy(android.location.Location);
-    method public static boolean isMock(android.location.Location);
-    method public static void setBearingAccuracyDegrees(android.location.Location, float);
-    method public static void setMock(android.location.Location, boolean);
-    method public static void setSpeedAccuracyMetersPerSecond(android.location.Location, float);
-    method public static void setVerticalAccuracyMeters(android.location.Location, float);
-    field public static final String EXTRA_BEARING_ACCURACY = "bearingAccuracy";
-    field public static final String EXTRA_IS_MOCK = "mockLocation";
-    field public static final String EXTRA_SPEED_ACCURACY = "speedAccuracy";
-    field public static final String EXTRA_VERTICAL_ACCURACY = "verticalAccuracy";
-  }
-
-  public interface LocationListenerCompat extends android.location.LocationListener {
-    method public default void onStatusChanged(String, int, android.os.Bundle?);
-  }
-
-  public final class LocationManagerCompat {
-    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void getCurrentLocation(android.location.LocationManager, String, androidx.core.os.CancellationSignal?, java.util.concurrent.Executor, androidx.core.util.Consumer<android.location.Location!>);
-    method public static String? getGnssHardwareModelName(android.location.LocationManager);
-    method public static int getGnssYearOfHardware(android.location.LocationManager);
-    method public static boolean hasProvider(android.location.LocationManager, String);
-    method public static boolean isLocationEnabled(android.location.LocationManager);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssStatusCallback(android.location.LocationManager, androidx.core.location.GnssStatusCompat.Callback, android.os.Handler);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssStatusCallback(android.location.LocationManager, java.util.concurrent.Executor, androidx.core.location.GnssStatusCompat.Callback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void removeUpdates(android.location.LocationManager, androidx.core.location.LocationListenerCompat);
-    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void requestLocationUpdates(android.location.LocationManager, String, androidx.core.location.LocationRequestCompat, java.util.concurrent.Executor, androidx.core.location.LocationListenerCompat);
-    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void requestLocationUpdates(android.location.LocationManager, String, androidx.core.location.LocationRequestCompat, androidx.core.location.LocationListenerCompat, android.os.Looper);
-    method public static void unregisterGnssStatusCallback(android.location.LocationManager, androidx.core.location.GnssStatusCompat.Callback);
-  }
-
-  public final class LocationRequestCompat {
-    method @IntRange(from=1) public long getDurationMillis();
-    method @IntRange(from=0) public long getIntervalMillis();
-    method @IntRange(from=0) public long getMaxUpdateDelayMillis();
-    method @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getMaxUpdates();
-    method @FloatRange(from=0, to=java.lang.Float.MAX_VALUE) public float getMinUpdateDistanceMeters();
-    method @IntRange(from=0) public long getMinUpdateIntervalMillis();
-    method public int getQuality();
-    method @RequiresApi(31) public android.location.LocationRequest toLocationRequest();
-    method @RequiresApi(19) public android.location.LocationRequest? toLocationRequest(String);
-    field public static final long PASSIVE_INTERVAL = 9223372036854775807L; // 0x7fffffffffffffffL
-    field public static final int QUALITY_BALANCED_POWER_ACCURACY = 102; // 0x66
-    field public static final int QUALITY_HIGH_ACCURACY = 100; // 0x64
-    field public static final int QUALITY_LOW_POWER = 104; // 0x68
-  }
-
-  public static final class LocationRequestCompat.Builder {
-    ctor public LocationRequestCompat.Builder(long);
-    ctor public LocationRequestCompat.Builder(androidx.core.location.LocationRequestCompat);
-    method public androidx.core.location.LocationRequestCompat build();
-    method public androidx.core.location.LocationRequestCompat.Builder clearMinUpdateIntervalMillis();
-    method public androidx.core.location.LocationRequestCompat.Builder setDurationMillis(@IntRange(from=1) long);
-    method public androidx.core.location.LocationRequestCompat.Builder setIntervalMillis(@IntRange(from=0) long);
-    method public androidx.core.location.LocationRequestCompat.Builder setMaxUpdateDelayMillis(@IntRange(from=0) long);
-    method public androidx.core.location.LocationRequestCompat.Builder setMaxUpdates(@IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int);
-    method public androidx.core.location.LocationRequestCompat.Builder setMinUpdateDistanceMeters(@FloatRange(from=0, to=java.lang.Float.MAX_VALUE) float);
-    method public androidx.core.location.LocationRequestCompat.Builder setMinUpdateIntervalMillis(@IntRange(from=0) long);
-    method public androidx.core.location.LocationRequestCompat.Builder setQuality(int);
-  }
-
-}
-
-package androidx.core.math {
-
-  public class MathUtils {
-    method public static int addExact(int, int);
-    method public static long addExact(long, long);
-    method public static float clamp(float, float, float);
-    method public static double clamp(double, double, double);
-    method public static int clamp(int, int, int);
-    method public static long clamp(long, long, long);
-    method public static int decrementExact(int);
-    method public static long decrementExact(long);
-    method public static int incrementExact(int);
-    method public static long incrementExact(long);
-    method public static int multiplyExact(int, int);
-    method public static long multiplyExact(long, long);
-    method public static int negateExact(int);
-    method public static long negateExact(long);
-    method public static int subtractExact(int, int);
-    method public static long subtractExact(long, long);
-    method public static int toIntExact(long);
-  }
-
-}
-
-package androidx.core.net {
-
-  public final class ConnectivityManagerCompat {
-    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static android.net.NetworkInfo? getNetworkInfoFromBroadcast(android.net.ConnectivityManager, android.content.Intent);
-    method public static int getRestrictBackgroundStatus(android.net.ConnectivityManager);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static boolean isActiveNetworkMetered(android.net.ConnectivityManager);
-    field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
-    field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
-    field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
-  }
-
-  public final class MailTo {
-    method public String? getBcc();
-    method public String? getBody();
-    method public String? getCc();
-    method public java.util.Map<java.lang.String!,java.lang.String!>? getHeaders();
-    method public String? getSubject();
-    method public String? getTo();
-    method public static boolean isMailTo(String?);
-    method public static boolean isMailTo(android.net.Uri?);
-    method public static androidx.core.net.MailTo parse(String) throws androidx.core.net.ParseException;
-    method public static androidx.core.net.MailTo parse(android.net.Uri) throws androidx.core.net.ParseException;
-    field public static final String MAILTO_SCHEME = "mailto:";
-  }
-
-  public class ParseException extends java.lang.RuntimeException {
-    field public final String response;
-  }
-
-  public final class TrafficStatsCompat {
-    method @Deprecated public static void clearThreadStatsTag();
-    method @Deprecated public static int getThreadStatsTag();
-    method @Deprecated public static void incrementOperationCount(int);
-    method @Deprecated public static void incrementOperationCount(int, int);
-    method @Deprecated public static void setThreadStatsTag(int);
-    method public static void tagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
-    method @Deprecated public static void tagSocket(java.net.Socket!) throws java.net.SocketException;
-    method public static void untagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
-    method @Deprecated public static void untagSocket(java.net.Socket!) throws java.net.SocketException;
-  }
-
-  public final class UriCompat {
-    method public static String toSafeString(android.net.Uri);
-  }
-
-}
-
-package androidx.core.os {
-
-  public class BuildCompat {
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.N) public static boolean isAtLeastN();
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.N_MR1) public static boolean isAtLeastNMR1();
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.O) public static boolean isAtLeastO();
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.O_MR1) public static boolean isAtLeastOMR1();
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.P) public static boolean isAtLeastP();
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.Q) public static boolean isAtLeastQ();
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.R) public static boolean isAtLeastR();
-    method @Deprecated @ChecksSdkIntAtLeast(api=31, codename="S") public static boolean isAtLeastS();
-  }
-
-  public final class CancellationSignal {
-    ctor public CancellationSignal();
-    method public void cancel();
-    method public Object? getCancellationSignalObject();
-    method public boolean isCanceled();
-    method public void setOnCancelListener(androidx.core.os.CancellationSignal.OnCancelListener?);
-    method public void throwIfCanceled();
-  }
-
-  public static interface CancellationSignal.OnCancelListener {
-    method public void onCancel();
-  }
-
-  public final class ConfigurationCompat {
-    method public static androidx.core.os.LocaleListCompat getLocales(android.content.res.Configuration);
-  }
-
-  public final class EnvironmentCompat {
-    method public static String getStorageState(java.io.File);
-    field public static final String MEDIA_UNKNOWN = "unknown";
-  }
-
-  public final class ExecutorCompat {
-    method public static java.util.concurrent.Executor create(android.os.Handler);
-  }
-
-  public final class HandlerCompat {
-    method public static android.os.Handler createAsync(android.os.Looper);
-    method public static android.os.Handler createAsync(android.os.Looper, android.os.Handler.Callback);
-    method @RequiresApi(16) public static boolean hasCallbacks(android.os.Handler, Runnable);
-    method public static boolean postDelayed(android.os.Handler, Runnable, Object?, long);
-  }
-
-  public final class LocaleListCompat {
-    method public static androidx.core.os.LocaleListCompat create(java.util.Locale!...);
-    method public static androidx.core.os.LocaleListCompat forLanguageTags(String?);
-    method public java.util.Locale? get(int);
-    method @Size(min=1) public static androidx.core.os.LocaleListCompat getAdjustedDefault();
-    method @Size(min=1) public static androidx.core.os.LocaleListCompat getDefault();
-    method public static androidx.core.os.LocaleListCompat getEmptyLocaleList();
-    method public java.util.Locale? getFirstMatch(String![]);
-    method @IntRange(from=0xffffffff) public int indexOf(java.util.Locale?);
-    method public boolean isEmpty();
-    method @IntRange(from=0) public int size();
-    method public String toLanguageTags();
-    method public Object? unwrap();
-    method @Deprecated @RequiresApi(24) public static androidx.core.os.LocaleListCompat! wrap(Object!);
-    method @RequiresApi(24) public static androidx.core.os.LocaleListCompat wrap(android.os.LocaleList);
-  }
-
-  public final class MessageCompat {
-    method public static boolean isAsynchronous(android.os.Message);
-    method public static void setAsynchronous(android.os.Message, boolean);
-  }
-
-  public class OperationCanceledException extends java.lang.RuntimeException {
-    ctor public OperationCanceledException();
-    ctor public OperationCanceledException(String?);
-  }
-
-  public final class ParcelCompat {
-    method public static boolean readBoolean(android.os.Parcel);
-    method public static void writeBoolean(android.os.Parcel, boolean);
-  }
-
-  @Deprecated public final class ParcelableCompat {
-    method @Deprecated public static <T> android.os.Parcelable.Creator<T!>! newCreator(androidx.core.os.ParcelableCompatCreatorCallbacks<T!>!);
-  }
-
-  @Deprecated public interface ParcelableCompatCreatorCallbacks<T> {
-    method @Deprecated public T! createFromParcel(android.os.Parcel!, ClassLoader!);
-    method @Deprecated public T![]! newArray(int);
-  }
-
-  public final class ProcessCompat {
-    method public static boolean isApplicationUid(int);
-  }
-
-  @Deprecated public final class TraceCompat {
-    method @Deprecated public static void beginAsyncSection(String, int);
-    method @Deprecated public static void beginSection(String);
-    method @Deprecated public static void endAsyncSection(String, int);
-    method @Deprecated public static void endSection();
-    method @Deprecated public static boolean isEnabled();
-    method @Deprecated public static void setCounter(String, int);
-  }
-
-  @RequiresApi(17) public class UserHandleCompat {
-    method public static android.os.UserHandle getUserHandleForUid(int);
-  }
-
-  public class UserManagerCompat {
-    method public static boolean isUserUnlocked(android.content.Context);
-  }
-
-}
-
-package androidx.core.provider {
-
-  public final class DocumentsContractCompat {
-    method public static android.net.Uri? buildChildDocumentsUri(String, String?);
-    method public static android.net.Uri? buildChildDocumentsUriUsingTree(android.net.Uri, String);
-    method public static android.net.Uri? buildDocumentUri(String, String);
-    method public static android.net.Uri? buildDocumentUriUsingTree(android.net.Uri, String);
-    method public static android.net.Uri? buildTreeDocumentUri(String, String);
-    method public static android.net.Uri? createDocument(android.content.ContentResolver, android.net.Uri, String, String) throws java.io.FileNotFoundException;
-    method public static String? getDocumentId(android.net.Uri);
-    method public static String? getTreeDocumentId(android.net.Uri);
-    method public static boolean isDocumentUri(android.content.Context, android.net.Uri?);
-    method public static boolean isTreeUri(android.net.Uri);
-    method public static boolean removeDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
-    method public static android.net.Uri? renameDocument(android.content.ContentResolver, android.net.Uri, String) throws java.io.FileNotFoundException;
-  }
-
-  public static final class DocumentsContractCompat.DocumentCompat {
-    field public static final int FLAG_VIRTUAL_DOCUMENT = 512; // 0x200
-  }
-
-  public final class FontRequest {
-    ctor public FontRequest(String, String, String, java.util.List<java.util.List<byte[]!>!>);
-    ctor public FontRequest(String, String, String, @ArrayRes int);
-    method public java.util.List<java.util.List<byte[]!>!>? getCertificates();
-    method @ArrayRes public int getCertificatesArrayResId();
-    method public String getProviderAuthority();
-    method public String getProviderPackage();
-    method public String getQuery();
-  }
-
-  public class FontsContractCompat {
-    method public static android.graphics.Typeface? buildTypeface(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo![]);
-    method public static androidx.core.provider.FontsContractCompat.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public static void requestFont(android.content.Context, androidx.core.provider.FontRequest, androidx.core.provider.FontsContractCompat.FontRequestCallback, android.os.Handler);
-  }
-
-  public static final class FontsContractCompat.Columns implements android.provider.BaseColumns {
-    ctor public FontsContractCompat.Columns();
-    field public static final String FILE_ID = "file_id";
-    field public static final String ITALIC = "font_italic";
-    field public static final String RESULT_CODE = "result_code";
-    field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
-    field public static final int RESULT_CODE_FONT_UNAVAILABLE = 2; // 0x2
-    field public static final int RESULT_CODE_MALFORMED_QUERY = 3; // 0x3
-    field public static final int RESULT_CODE_OK = 0; // 0x0
-    field public static final String TTC_INDEX = "font_ttc_index";
-    field public static final String VARIATION_SETTINGS = "font_variation_settings";
-    field public static final String WEIGHT = "font_weight";
-  }
-
-  public static class FontsContractCompat.FontFamilyResult {
-    method public androidx.core.provider.FontsContractCompat.FontInfo![]! getFonts();
-    method public int getStatusCode();
-    field public static final int STATUS_OK = 0; // 0x0
-    field public static final int STATUS_UNEXPECTED_DATA_PROVIDED = 2; // 0x2
-    field public static final int STATUS_WRONG_CERTIFICATES = 1; // 0x1
-  }
-
-  public static class FontsContractCompat.FontInfo {
-    method public int getResultCode();
-    method @IntRange(from=0) public int getTtcIndex();
-    method public android.net.Uri getUri();
-    method @IntRange(from=1, to=1000) public int getWeight();
-    method public boolean isItalic();
-  }
-
-  public static class FontsContractCompat.FontRequestCallback {
-    ctor public FontsContractCompat.FontRequestCallback();
-    method public void onTypefaceRequestFailed(int);
-    method public void onTypefaceRetrieved(android.graphics.Typeface!);
-    field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
-    field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
-    field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
-    field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
-    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
-    field public static final int FAIL_REASON_SECURITY_VIOLATION = -4; // 0xfffffffc
-    field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
-  }
-
-}
-
-package androidx.core.telephony {
-
-  @RequiresApi(22) public class SubscriptionManagerCompat {
-    method public static int getSlotIndex(int);
-  }
-
-  public class TelephonyManagerCompat {
-    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static String? getImei(android.telephony.TelephonyManager);
-    method public static int getSubscriptionId(android.telephony.TelephonyManager);
-  }
-
-}
-
-package androidx.core.telephony.mbms {
-
-  public final class MbmsHelper {
-    method public static CharSequence? getBestNameForService(android.content.Context, android.telephony.mbms.ServiceInfo);
-  }
-
-}
-
-package androidx.core.text {
-
-  public final class BidiFormatter {
-    method public static androidx.core.text.BidiFormatter! getInstance();
-    method public static androidx.core.text.BidiFormatter! getInstance(boolean);
-    method public static androidx.core.text.BidiFormatter! getInstance(java.util.Locale!);
-    method public boolean getStereoReset();
-    method public boolean isRtl(String!);
-    method public boolean isRtl(CharSequence!);
-    method public boolean isRtlContext();
-    method public String! unicodeWrap(String!, androidx.core.text.TextDirectionHeuristicCompat!, boolean);
-    method public CharSequence! unicodeWrap(CharSequence!, androidx.core.text.TextDirectionHeuristicCompat!, boolean);
-    method public String! unicodeWrap(String!, androidx.core.text.TextDirectionHeuristicCompat!);
-    method public CharSequence! unicodeWrap(CharSequence!, androidx.core.text.TextDirectionHeuristicCompat!);
-    method public String! unicodeWrap(String!, boolean);
-    method public CharSequence! unicodeWrap(CharSequence!, boolean);
-    method public String! unicodeWrap(String!);
-    method public CharSequence! unicodeWrap(CharSequence!);
-  }
-
-  public static final class BidiFormatter.Builder {
-    ctor public BidiFormatter.Builder();
-    ctor public BidiFormatter.Builder(boolean);
-    ctor public BidiFormatter.Builder(java.util.Locale!);
-    method public androidx.core.text.BidiFormatter! build();
-    method public androidx.core.text.BidiFormatter.Builder! setTextDirectionHeuristic(androidx.core.text.TextDirectionHeuristicCompat!);
-    method public androidx.core.text.BidiFormatter.Builder! stereoReset(boolean);
-  }
-
-  public final class HtmlCompat {
-    method public static android.text.Spanned fromHtml(String, int);
-    method public static android.text.Spanned fromHtml(String, int, android.text.Html.ImageGetter?, android.text.Html.TagHandler?);
-    method public static String toHtml(android.text.Spanned, int);
-    field public static final int FROM_HTML_MODE_COMPACT = 63; // 0x3f
-    field public static final int FROM_HTML_MODE_LEGACY = 0; // 0x0
-    field public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256; // 0x100
-    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32; // 0x20
-    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16; // 0x10
-    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2; // 0x2
-    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8; // 0x8
-    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4; // 0x4
-    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1; // 0x1
-    field public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0; // 0x0
-    field public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1; // 0x1
-  }
-
-  public final class ICUCompat {
-    method public static String? maximizeAndGetScript(java.util.Locale);
-  }
-
-  public class PrecomputedTextCompat implements android.text.Spannable {
-    method public char charAt(int);
-    method public static androidx.core.text.PrecomputedTextCompat! create(CharSequence, androidx.core.text.PrecomputedTextCompat.Params);
-    method @IntRange(from=0) public int getParagraphCount();
-    method @IntRange(from=0) public int getParagraphEnd(@IntRange(from=0) int);
-    method @IntRange(from=0) public int getParagraphStart(@IntRange(from=0) int);
-    method public androidx.core.text.PrecomputedTextCompat.Params getParams();
-    method public int getSpanEnd(Object!);
-    method public int getSpanFlags(Object!);
-    method public int getSpanStart(Object!);
-    method public <T> T![]! getSpans(int, int, Class<T!>!);
-    method @UiThread public static java.util.concurrent.Future<androidx.core.text.PrecomputedTextCompat!>! getTextFuture(CharSequence, androidx.core.text.PrecomputedTextCompat.Params, java.util.concurrent.Executor?);
-    method public int length();
-    method public int nextSpanTransition(int, int, Class!);
-    method public void removeSpan(Object!);
-    method public void setSpan(Object!, int, int, int);
-    method public CharSequence! subSequence(int, int);
-  }
-
-  public static final class PrecomputedTextCompat.Params {
-    ctor @RequiresApi(28) public PrecomputedTextCompat.Params(android.text.PrecomputedText.Params);
-    method @RequiresApi(23) public int getBreakStrategy();
-    method @RequiresApi(23) public int getHyphenationFrequency();
-    method @RequiresApi(18) public android.text.TextDirectionHeuristic? getTextDirection();
-    method public android.text.TextPaint getTextPaint();
-  }
-
-  public static class PrecomputedTextCompat.Params.Builder {
-    ctor public PrecomputedTextCompat.Params.Builder(android.text.TextPaint);
-    method public androidx.core.text.PrecomputedTextCompat.Params build();
-    method @RequiresApi(23) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setBreakStrategy(int);
-    method @RequiresApi(23) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setHyphenationFrequency(int);
-    method @RequiresApi(18) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setTextDirection(android.text.TextDirectionHeuristic);
-  }
-
-  public interface TextDirectionHeuristicCompat {
-    method public boolean isRtl(char[]!, int, int);
-    method public boolean isRtl(CharSequence!, int, int);
-  }
-
-  public final class TextDirectionHeuristicsCompat {
-    field public static final androidx.core.text.TextDirectionHeuristicCompat! ANYRTL_LTR;
-    field public static final androidx.core.text.TextDirectionHeuristicCompat! FIRSTSTRONG_LTR;
-    field public static final androidx.core.text.TextDirectionHeuristicCompat! FIRSTSTRONG_RTL;
-    field public static final androidx.core.text.TextDirectionHeuristicCompat! LOCALE;
-    field public static final androidx.core.text.TextDirectionHeuristicCompat! LTR;
-    field public static final androidx.core.text.TextDirectionHeuristicCompat! RTL;
-  }
-
-  public final class TextUtilsCompat {
-    method public static int getLayoutDirectionFromLocale(java.util.Locale?);
-    method public static String htmlEncode(String);
-  }
-
-}
-
-package androidx.core.text.util {
-
-  public final class LinkifyCompat {
-    method public static boolean addLinks(android.text.Spannable, int);
-    method public static boolean addLinks(android.widget.TextView, int);
-    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?);
-    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
-    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?, String![]?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
-    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?);
-    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
-    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?, String![]?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
-  }
-
-}
-
-package androidx.core.util {
-
-  public class AtomicFile {
-    ctor public AtomicFile(java.io.File);
-    method public void delete();
-    method public void failWrite(java.io.FileOutputStream?);
-    method public void finishWrite(java.io.FileOutputStream?);
-    method public java.io.File getBaseFile();
-    method public java.io.FileInputStream openRead() throws java.io.FileNotFoundException;
-    method public byte[] readFully() throws java.io.IOException;
-    method public java.io.FileOutputStream startWrite() throws java.io.IOException;
-  }
-
-  public interface Consumer<T> {
-    method public void accept(T!);
-  }
-
-  public class ObjectsCompat {
-    method public static boolean equals(Object?, Object?);
-    method public static int hash(java.lang.Object!...);
-    method public static int hashCode(Object?);
-    method public static <T> T requireNonNull(T?);
-    method public static <T> T requireNonNull(T?, String);
-    method public static String? toString(Object?, String?);
-  }
-
-  public class Pair<F, S> {
-    ctor public Pair(F!, S!);
-    method public static <A, B> androidx.core.util.Pair<A!,B!> create(A!, B!);
-    field public final F! first;
-    field public final S! second;
-  }
-
-  public final class PatternsCompat {
-    field public static final java.util.regex.Pattern DOMAIN_NAME;
-    field public static final java.util.regex.Pattern EMAIL_ADDRESS;
-    field public static final java.util.regex.Pattern IP_ADDRESS;
-    field public static final java.util.regex.Pattern WEB_URL;
-  }
-
-  public final class Pools {
-  }
-
-  public static interface Pools.Pool<T> {
-    method public T? acquire();
-    method public boolean release(T);
-  }
-
-  public static class Pools.SimplePool<T> implements androidx.core.util.Pools.Pool<T> {
-    ctor public Pools.SimplePool(int);
-    method public T! acquire();
-    method public boolean release(T);
-  }
-
-  public static class Pools.SynchronizedPool<T> extends androidx.core.util.Pools.SimplePool<T> {
-    ctor public Pools.SynchronizedPool(int);
-  }
-
-  public interface Predicate<T> {
-    method public boolean test(T!);
-  }
-
-  public final class SizeFCompat {
-    ctor public SizeFCompat(float, float);
-    method public float getHeight();
-    method public float getWidth();
-    method @RequiresApi(21) public android.util.SizeF toSizeF();
-    method @RequiresApi(21) public static androidx.core.util.SizeFCompat toSizeFCompat(android.util.SizeF);
-  }
-
-  public interface Supplier<T> {
-    method public T! get();
-  }
-
-}
-
-package androidx.core.view {
-
-  public class AccessibilityDelegateCompat {
-    ctor public AccessibilityDelegateCompat();
-    method public boolean dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
-    method public androidx.core.view.accessibility.AccessibilityNodeProviderCompat? getAccessibilityNodeProvider(android.view.View);
-    method public void onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
-    method public void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
-    method public void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
-    method public boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
-    method public boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
-    method public void sendAccessibilityEvent(android.view.View, int);
-    method public void sendAccessibilityEventUnchecked(android.view.View, android.view.accessibility.AccessibilityEvent);
-  }
-
-  public abstract class ActionProvider {
-    ctor public ActionProvider(android.content.Context);
-    method public android.content.Context getContext();
-    method public boolean hasSubMenu();
-    method public boolean isVisible();
-    method public abstract android.view.View onCreateActionView();
-    method public android.view.View onCreateActionView(android.view.MenuItem);
-    method public boolean onPerformDefaultAction();
-    method public void onPrepareSubMenu(android.view.SubMenu);
-    method public boolean overridesItemVisibility();
-    method public void refreshVisibility();
-    method public void setVisibilityListener(androidx.core.view.ActionProvider.VisibilityListener?);
-  }
-
-  public static interface ActionProvider.VisibilityListener {
-    method public void onActionProviderVisibilityChanged(boolean);
-  }
-
-  public final class ContentInfoCompat {
-    method public android.content.ClipData getClip();
-    method public android.os.Bundle? getExtras();
-    method public int getFlags();
-    method public android.net.Uri? getLinkUri();
-    method public int getSource();
-    method public android.util.Pair<androidx.core.view.ContentInfoCompat!,androidx.core.view.ContentInfoCompat!> partition(androidx.core.util.Predicate<android.content.ClipData.Item!>);
-    method @RequiresApi(31) public static android.util.Pair<android.view.ContentInfo!,android.view.ContentInfo!> partition(android.view.ContentInfo, java.util.function.Predicate<android.content.ClipData.Item!>);
-    method @RequiresApi(31) public android.view.ContentInfo toContentInfo();
-    method @RequiresApi(31) public static androidx.core.view.ContentInfoCompat toContentInfoCompat(android.view.ContentInfo);
-    field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1
-    field public static final int SOURCE_APP = 0; // 0x0
-    field public static final int SOURCE_AUTOFILL = 4; // 0x4
-    field public static final int SOURCE_CLIPBOARD = 1; // 0x1
-    field public static final int SOURCE_DRAG_AND_DROP = 3; // 0x3
-    field public static final int SOURCE_INPUT_METHOD = 2; // 0x2
-    field public static final int SOURCE_PROCESS_TEXT = 5; // 0x5
-  }
-
-  public static final class ContentInfoCompat.Builder {
-    ctor public ContentInfoCompat.Builder(androidx.core.view.ContentInfoCompat);
-    ctor public ContentInfoCompat.Builder(android.content.ClipData, int);
-    method public androidx.core.view.ContentInfoCompat build();
-    method public androidx.core.view.ContentInfoCompat.Builder setClip(android.content.ClipData);
-    method public androidx.core.view.ContentInfoCompat.Builder setExtras(android.os.Bundle?);
-    method public androidx.core.view.ContentInfoCompat.Builder setFlags(int);
-    method public androidx.core.view.ContentInfoCompat.Builder setLinkUri(android.net.Uri?);
-    method public androidx.core.view.ContentInfoCompat.Builder setSource(int);
-  }
-
-  public final class DisplayCompat {
-    method public static androidx.core.view.DisplayCompat.ModeCompat getMode(android.content.Context, android.view.Display);
-    method public static androidx.core.view.DisplayCompat.ModeCompat![] getSupportedModes(android.content.Context, android.view.Display);
-  }
-
-  public static final class DisplayCompat.ModeCompat {
-    method public int getPhysicalHeight();
-    method public int getPhysicalWidth();
-    method @Deprecated public boolean isNative();
-    method @RequiresApi(android.os.Build.VERSION_CODES.M) public android.view.Display.Mode? toMode();
-  }
-
-  public final class DisplayCutoutCompat {
-    ctor public DisplayCutoutCompat(android.graphics.Rect?, java.util.List<android.graphics.Rect!>?);
-    ctor public DisplayCutoutCompat(androidx.core.graphics.Insets, android.graphics.Rect?, android.graphics.Rect?, android.graphics.Rect?, android.graphics.Rect?, androidx.core.graphics.Insets);
-    method public java.util.List<android.graphics.Rect!> getBoundingRects();
-    method public int getSafeInsetBottom();
-    method public int getSafeInsetLeft();
-    method public int getSafeInsetRight();
-    method public int getSafeInsetTop();
-    method public androidx.core.graphics.Insets getWaterfallInsets();
-  }
-
-  public final class DragAndDropPermissionsCompat {
-    method public void release();
-  }
-
-  public class DragStartHelper {
-    ctor public DragStartHelper(android.view.View, androidx.core.view.DragStartHelper.OnDragStartListener);
-    method public void attach();
-    method public void detach();
-    method public void getTouchPosition(android.graphics.Point);
-    method public boolean onLongClick(android.view.View);
-    method public boolean onTouch(android.view.View, android.view.MotionEvent);
-  }
-
-  public static interface DragStartHelper.OnDragStartListener {
-    method public boolean onDragStart(android.view.View, androidx.core.view.DragStartHelper);
-  }
-
-  public final class GestureDetectorCompat {
-    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener);
-    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler?);
-    method public boolean isLongpressEnabled();
-    method public boolean onTouchEvent(android.view.MotionEvent);
-    method public void setIsLongpressEnabled(boolean);
-    method public void setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener?);
-  }
-
-  public final class GravityCompat {
-    method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect, int);
-    method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect, int);
-    method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect, int);
-    method public static int getAbsoluteGravity(int, int);
-    field public static final int END = 8388613; // 0x800005
-    field public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = 8388615; // 0x800007
-    field public static final int RELATIVE_LAYOUT_DIRECTION = 8388608; // 0x800000
-    field public static final int START = 8388611; // 0x800003
-  }
-
-  public final class InputDeviceCompat {
-    field public static final int SOURCE_ANY = -256; // 0xffffff00
-    field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
-    field public static final int SOURCE_CLASS_JOYSTICK = 16; // 0x10
-    field public static final int SOURCE_CLASS_MASK = 255; // 0xff
-    field public static final int SOURCE_CLASS_NONE = 0; // 0x0
-    field public static final int SOURCE_CLASS_POINTER = 2; // 0x2
-    field public static final int SOURCE_CLASS_POSITION = 8; // 0x8
-    field public static final int SOURCE_CLASS_TRACKBALL = 4; // 0x4
-    field public static final int SOURCE_DPAD = 513; // 0x201
-    field public static final int SOURCE_GAMEPAD = 1025; // 0x401
-    field public static final int SOURCE_HDMI = 33554433; // 0x2000001
-    field public static final int SOURCE_JOYSTICK = 16777232; // 0x1000010
-    field public static final int SOURCE_KEYBOARD = 257; // 0x101
-    field public static final int SOURCE_MOUSE = 8194; // 0x2002
-    field public static final int SOURCE_ROTARY_ENCODER = 4194304; // 0x400000
-    field public static final int SOURCE_STYLUS = 16386; // 0x4002
-    field public static final int SOURCE_TOUCHPAD = 1048584; // 0x100008
-    field public static final int SOURCE_TOUCHSCREEN = 4098; // 0x1002
-    field public static final int SOURCE_TOUCH_NAVIGATION = 2097152; // 0x200000
-    field public static final int SOURCE_TRACKBALL = 65540; // 0x10004
-    field public static final int SOURCE_UNKNOWN = 0; // 0x0
-  }
-
-  public final class LayoutInflaterCompat {
-    method @Deprecated public static androidx.core.view.LayoutInflaterFactory! getFactory(android.view.LayoutInflater!);
-    method @Deprecated public static void setFactory(android.view.LayoutInflater, androidx.core.view.LayoutInflaterFactory);
-    method public static void setFactory2(android.view.LayoutInflater, android.view.LayoutInflater.Factory2);
-  }
-
-  @Deprecated public interface LayoutInflaterFactory {
-    method @Deprecated public android.view.View! onCreateView(android.view.View!, String!, android.content.Context!, android.util.AttributeSet!);
-  }
-
-  public final class MarginLayoutParamsCompat {
-    method public static int getLayoutDirection(android.view.ViewGroup.MarginLayoutParams);
-    method public static int getMarginEnd(android.view.ViewGroup.MarginLayoutParams);
-    method public static int getMarginStart(android.view.ViewGroup.MarginLayoutParams);
-    method public static boolean isMarginRelative(android.view.ViewGroup.MarginLayoutParams);
-    method public static void resolveLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
-    method public static void setLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
-    method public static void setMarginEnd(android.view.ViewGroup.MarginLayoutParams, int);
-    method public static void setMarginStart(android.view.ViewGroup.MarginLayoutParams, int);
-  }
-
-  public final class MenuCompat {
-    method public static void setGroupDividerEnabled(android.view.Menu, boolean);
-    method @Deprecated public static void setShowAsAction(android.view.MenuItem!, int);
-  }
-
-  public interface MenuHost {
-    method public void addMenuProvider(androidx.core.view.MenuProvider);
-    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner);
-    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State);
-    method public void invalidateMenu();
-    method public void removeMenuProvider(androidx.core.view.MenuProvider);
-  }
-
-  public class MenuHostHelper {
-    ctor public MenuHostHelper(Runnable);
-    method public void addMenuProvider(androidx.core.view.MenuProvider);
-    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner);
-    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State);
-    method public void onCreateMenu(android.view.Menu, android.view.MenuInflater);
-    method public void onMenuClosed(android.view.Menu);
-    method public boolean onMenuItemSelected(android.view.MenuItem);
-    method public void onPrepareMenu(android.view.Menu);
-    method public void removeMenuProvider(androidx.core.view.MenuProvider);
-  }
-
-  public final class MenuItemCompat {
-    method @Deprecated public static boolean collapseActionView(android.view.MenuItem!);
-    method @Deprecated public static boolean expandActionView(android.view.MenuItem!);
-    method public static androidx.core.view.ActionProvider? getActionProvider(android.view.MenuItem);
-    method @Deprecated public static android.view.View! getActionView(android.view.MenuItem!);
-    method public static int getAlphabeticModifiers(android.view.MenuItem);
-    method public static CharSequence? getContentDescription(android.view.MenuItem);
-    method public static android.content.res.ColorStateList? getIconTintList(android.view.MenuItem);
-    method public static android.graphics.PorterDuff.Mode? getIconTintMode(android.view.MenuItem);
-    method public static int getNumericModifiers(android.view.MenuItem);
-    method public static CharSequence? getTooltipText(android.view.MenuItem);
-    method @Deprecated public static boolean isActionViewExpanded(android.view.MenuItem!);
-    method public static android.view.MenuItem? setActionProvider(android.view.MenuItem, androidx.core.view.ActionProvider?);
-    method @Deprecated public static android.view.MenuItem! setActionView(android.view.MenuItem!, android.view.View!);
-    method @Deprecated public static android.view.MenuItem! setActionView(android.view.MenuItem!, int);
-    method public static void setAlphabeticShortcut(android.view.MenuItem, char, int);
-    method public static void setContentDescription(android.view.MenuItem, CharSequence?);
-    method public static void setIconTintList(android.view.MenuItem, android.content.res.ColorStateList?);
-    method public static void setIconTintMode(android.view.MenuItem, android.graphics.PorterDuff.Mode?);
-    method public static void setNumericShortcut(android.view.MenuItem, char, int);
-    method @Deprecated public static android.view.MenuItem! setOnActionExpandListener(android.view.MenuItem!, androidx.core.view.MenuItemCompat.OnActionExpandListener!);
-    method public static void setShortcut(android.view.MenuItem, char, char, int, int);
-    method @Deprecated public static void setShowAsAction(android.view.MenuItem!, int);
-    method public static void setTooltipText(android.view.MenuItem, CharSequence?);
-    field @Deprecated public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
-    field @Deprecated public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; // 0x8
-    field @Deprecated public static final int SHOW_AS_ACTION_IF_ROOM = 1; // 0x1
-    field @Deprecated public static final int SHOW_AS_ACTION_NEVER = 0; // 0x0
-    field @Deprecated public static final int SHOW_AS_ACTION_WITH_TEXT = 4; // 0x4
-  }
-
-  @Deprecated public static interface MenuItemCompat.OnActionExpandListener {
-    method @Deprecated public boolean onMenuItemActionCollapse(android.view.MenuItem!);
-    method @Deprecated public boolean onMenuItemActionExpand(android.view.MenuItem!);
-  }
-
-  public interface MenuProvider {
-    method public void onCreateMenu(android.view.Menu, android.view.MenuInflater);
-    method public default void onMenuClosed(android.view.Menu);
-    method public boolean onMenuItemSelected(android.view.MenuItem);
-    method public default void onPrepareMenu(android.view.Menu);
-  }
-
-  public final class MotionEventCompat {
-    method @Deprecated public static int findPointerIndex(android.view.MotionEvent!, int);
-    method @Deprecated public static int getActionIndex(android.view.MotionEvent!);
-    method @Deprecated public static int getActionMasked(android.view.MotionEvent!);
-    method @Deprecated public static float getAxisValue(android.view.MotionEvent!, int);
-    method @Deprecated public static float getAxisValue(android.view.MotionEvent!, int, int);
-    method @Deprecated public static int getButtonState(android.view.MotionEvent!);
-    method @Deprecated public static int getPointerCount(android.view.MotionEvent!);
-    method @Deprecated public static int getPointerId(android.view.MotionEvent!, int);
-    method @Deprecated public static int getSource(android.view.MotionEvent!);
-    method @Deprecated public static float getX(android.view.MotionEvent!, int);
-    method @Deprecated public static float getY(android.view.MotionEvent!, int);
-    method public static boolean isFromSource(android.view.MotionEvent, int);
-    field @Deprecated public static final int ACTION_HOVER_ENTER = 9; // 0x9
-    field @Deprecated public static final int ACTION_HOVER_EXIT = 10; // 0xa
-    field @Deprecated public static final int ACTION_HOVER_MOVE = 7; // 0x7
-    field @Deprecated public static final int ACTION_MASK = 255; // 0xff
-    field @Deprecated public static final int ACTION_POINTER_DOWN = 5; // 0x5
-    field @Deprecated public static final int ACTION_POINTER_INDEX_MASK = 65280; // 0xff00
-    field @Deprecated public static final int ACTION_POINTER_INDEX_SHIFT = 8; // 0x8
-    field @Deprecated public static final int ACTION_POINTER_UP = 6; // 0x6
-    field @Deprecated public static final int ACTION_SCROLL = 8; // 0x8
-    field @Deprecated public static final int AXIS_BRAKE = 23; // 0x17
-    field @Deprecated public static final int AXIS_DISTANCE = 24; // 0x18
-    field @Deprecated public static final int AXIS_GAS = 22; // 0x16
-    field @Deprecated public static final int AXIS_GENERIC_1 = 32; // 0x20
-    field @Deprecated public static final int AXIS_GENERIC_10 = 41; // 0x29
-    field @Deprecated public static final int AXIS_GENERIC_11 = 42; // 0x2a
-    field @Deprecated public static final int AXIS_GENERIC_12 = 43; // 0x2b
-    field @Deprecated public static final int AXIS_GENERIC_13 = 44; // 0x2c
-    field @Deprecated public static final int AXIS_GENERIC_14 = 45; // 0x2d
-    field @Deprecated public static final int AXIS_GENERIC_15 = 46; // 0x2e
-    field @Deprecated public static final int AXIS_GENERIC_16 = 47; // 0x2f
-    field @Deprecated public static final int AXIS_GENERIC_2 = 33; // 0x21
-    field @Deprecated public static final int AXIS_GENERIC_3 = 34; // 0x22
-    field @Deprecated public static final int AXIS_GENERIC_4 = 35; // 0x23
-    field @Deprecated public static final int AXIS_GENERIC_5 = 36; // 0x24
-    field @Deprecated public static final int AXIS_GENERIC_6 = 37; // 0x25
-    field @Deprecated public static final int AXIS_GENERIC_7 = 38; // 0x26
-    field @Deprecated public static final int AXIS_GENERIC_8 = 39; // 0x27
-    field @Deprecated public static final int AXIS_GENERIC_9 = 40; // 0x28
-    field @Deprecated public static final int AXIS_HAT_X = 15; // 0xf
-    field @Deprecated public static final int AXIS_HAT_Y = 16; // 0x10
-    field @Deprecated public static final int AXIS_HSCROLL = 10; // 0xa
-    field @Deprecated public static final int AXIS_LTRIGGER = 17; // 0x11
-    field @Deprecated public static final int AXIS_ORIENTATION = 8; // 0x8
-    field @Deprecated public static final int AXIS_PRESSURE = 2; // 0x2
-    field public static final int AXIS_RELATIVE_X = 27; // 0x1b
-    field public static final int AXIS_RELATIVE_Y = 28; // 0x1c
-    field @Deprecated public static final int AXIS_RTRIGGER = 18; // 0x12
-    field @Deprecated public static final int AXIS_RUDDER = 20; // 0x14
-    field @Deprecated public static final int AXIS_RX = 12; // 0xc
-    field @Deprecated public static final int AXIS_RY = 13; // 0xd
-    field @Deprecated public static final int AXIS_RZ = 14; // 0xe
-    field public static final int AXIS_SCROLL = 26; // 0x1a
-    field @Deprecated public static final int AXIS_SIZE = 3; // 0x3
-    field @Deprecated public static final int AXIS_THROTTLE = 19; // 0x13
-    field @Deprecated public static final int AXIS_TILT = 25; // 0x19
-    field @Deprecated public static final int AXIS_TOOL_MAJOR = 6; // 0x6
-    field @Deprecated public static final int AXIS_TOOL_MINOR = 7; // 0x7
-    field @Deprecated public static final int AXIS_TOUCH_MAJOR = 4; // 0x4
-    field @Deprecated public static final int AXIS_TOUCH_MINOR = 5; // 0x5
-    field @Deprecated public static final int AXIS_VSCROLL = 9; // 0x9
-    field @Deprecated public static final int AXIS_WHEEL = 21; // 0x15
-    field @Deprecated public static final int AXIS_X = 0; // 0x0
-    field @Deprecated public static final int AXIS_Y = 1; // 0x1
-    field @Deprecated public static final int AXIS_Z = 11; // 0xb
-    field @Deprecated public static final int BUTTON_PRIMARY = 1; // 0x1
-  }
-
-  public interface NestedScrollingChild {
-    method public boolean dispatchNestedFling(float, float, boolean);
-    method public boolean dispatchNestedPreFling(float, float);
-    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?);
-    method public boolean dispatchNestedScroll(int, int, int, int, int[]?);
-    method public boolean hasNestedScrollingParent();
-    method public boolean isNestedScrollingEnabled();
-    method public void setNestedScrollingEnabled(boolean);
-    method public boolean startNestedScroll(int);
-    method public void stopNestedScroll();
-  }
-
-  public interface NestedScrollingChild2 extends androidx.core.view.NestedScrollingChild {
-    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
-    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
-    method public boolean hasNestedScrollingParent(int);
-    method public boolean startNestedScroll(int, int);
-    method public void stopNestedScroll(int);
-  }
-
-  public interface NestedScrollingChild3 extends androidx.core.view.NestedScrollingChild2 {
-    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]);
-  }
-
-  public class NestedScrollingChildHelper {
-    ctor public NestedScrollingChildHelper(android.view.View);
-    method public boolean dispatchNestedFling(float, float, boolean);
-    method public boolean dispatchNestedPreFling(float, float);
-    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?);
-    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
-    method public boolean dispatchNestedScroll(int, int, int, int, int[]?);
-    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
-    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]?);
-    method public boolean hasNestedScrollingParent();
-    method public boolean hasNestedScrollingParent(int);
-    method public boolean isNestedScrollingEnabled();
-    method public void onDetachedFromWindow();
-    method public void onStopNestedScroll(android.view.View);
-    method public void setNestedScrollingEnabled(boolean);
-    method public boolean startNestedScroll(int);
-    method public boolean startNestedScroll(int, int);
-    method public void stopNestedScroll();
-    method public void stopNestedScroll(int);
-  }
-
-  public interface NestedScrollingParent {
-    method public int getNestedScrollAxes();
-    method public boolean onNestedFling(android.view.View, float, float, boolean);
-    method public boolean onNestedPreFling(android.view.View, float, float);
-    method public void onNestedPreScroll(android.view.View, int, int, int[]);
-    method public void onNestedScroll(android.view.View, int, int, int, int);
-    method public void onNestedScrollAccepted(android.view.View, android.view.View, int);
-    method public boolean onStartNestedScroll(android.view.View, android.view.View, int);
-    method public void onStopNestedScroll(android.view.View);
-  }
-
-  public interface NestedScrollingParent2 extends androidx.core.view.NestedScrollingParent {
-    method public void onNestedPreScroll(android.view.View, int, int, int[], int);
-    method public void onNestedScroll(android.view.View, int, int, int, int, int);
-    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
-    method public boolean onStartNestedScroll(android.view.View, android.view.View, int, int);
-    method public void onStopNestedScroll(android.view.View, int);
-  }
-
-  public interface NestedScrollingParent3 extends androidx.core.view.NestedScrollingParent2 {
-    method public void onNestedScroll(android.view.View, int, int, int, int, int, int[]);
-  }
-
-  public class NestedScrollingParentHelper {
-    ctor public NestedScrollingParentHelper(android.view.ViewGroup);
-    method public int getNestedScrollAxes();
-    method public void onNestedScrollAccepted(android.view.View, android.view.View, int);
-    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
-    method public void onStopNestedScroll(android.view.View);
-    method public void onStopNestedScroll(android.view.View, int);
-  }
-
-  public interface OnApplyWindowInsetsListener {
-    method public androidx.core.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
-  }
-
-  public interface OnReceiveContentListener {
-    method public androidx.core.view.ContentInfoCompat? onReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
-  }
-
-  public interface OnReceiveContentViewBehavior {
-    method public androidx.core.view.ContentInfoCompat? onReceiveContent(androidx.core.view.ContentInfoCompat);
-  }
-
-  public final class OneShotPreDrawListener implements android.view.View.OnAttachStateChangeListener android.view.ViewTreeObserver.OnPreDrawListener {
-    method public static androidx.core.view.OneShotPreDrawListener add(android.view.View, Runnable);
-    method public boolean onPreDraw();
-    method public void onViewAttachedToWindow(android.view.View);
-    method public void onViewDetachedFromWindow(android.view.View);
-    method public void removeListener();
-  }
-
-  public final class PointerIconCompat {
-    method public static androidx.core.view.PointerIconCompat create(android.graphics.Bitmap, float, float);
-    method public static androidx.core.view.PointerIconCompat getSystemIcon(android.content.Context, int);
-    method public static androidx.core.view.PointerIconCompat load(android.content.res.Resources, int);
-    field public static final int TYPE_ALIAS = 1010; // 0x3f2
-    field public static final int TYPE_ALL_SCROLL = 1013; // 0x3f5
-    field public static final int TYPE_ARROW = 1000; // 0x3e8
-    field public static final int TYPE_CELL = 1006; // 0x3ee
-    field public static final int TYPE_CONTEXT_MENU = 1001; // 0x3e9
-    field public static final int TYPE_COPY = 1011; // 0x3f3
-    field public static final int TYPE_CROSSHAIR = 1007; // 0x3ef
-    field public static final int TYPE_DEFAULT = 1000; // 0x3e8
-    field public static final int TYPE_GRAB = 1020; // 0x3fc
-    field public static final int TYPE_GRABBING = 1021; // 0x3fd
-    field public static final int TYPE_HAND = 1002; // 0x3ea
-    field public static final int TYPE_HELP = 1003; // 0x3eb
-    field public static final int TYPE_HORIZONTAL_DOUBLE_ARROW = 1014; // 0x3f6
-    field public static final int TYPE_NO_DROP = 1012; // 0x3f4
-    field public static final int TYPE_NULL = 0; // 0x0
-    field public static final int TYPE_TEXT = 1008; // 0x3f0
-    field public static final int TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW = 1017; // 0x3f9
-    field public static final int TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW = 1016; // 0x3f8
-    field public static final int TYPE_VERTICAL_DOUBLE_ARROW = 1015; // 0x3f7
-    field public static final int TYPE_VERTICAL_TEXT = 1009; // 0x3f1
-    field public static final int TYPE_WAIT = 1004; // 0x3ec
-    field public static final int TYPE_ZOOM_IN = 1018; // 0x3fa
-    field public static final int TYPE_ZOOM_OUT = 1019; // 0x3fb
-  }
-
-  public final class ScaleGestureDetectorCompat {
-    method @Deprecated public static boolean isQuickScaleEnabled(Object!);
-    method public static boolean isQuickScaleEnabled(android.view.ScaleGestureDetector);
-    method @Deprecated public static void setQuickScaleEnabled(Object!, boolean);
-    method public static void setQuickScaleEnabled(android.view.ScaleGestureDetector, boolean);
-  }
-
-  public interface ScrollingView {
-    method public int computeHorizontalScrollExtent();
-    method public int computeHorizontalScrollOffset();
-    method public int computeHorizontalScrollRange();
-    method public int computeVerticalScrollExtent();
-    method public int computeVerticalScrollOffset();
-    method public int computeVerticalScrollRange();
-  }
-
-  public interface TintableBackgroundView {
-    method public android.content.res.ColorStateList? getSupportBackgroundTintList();
-    method public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
-    method public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
-    method public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
-  }
-
-  @Deprecated public final class VelocityTrackerCompat {
-    method @Deprecated public static float getXVelocity(android.view.VelocityTracker!, int);
-    method @Deprecated public static float getYVelocity(android.view.VelocityTracker!, int);
-  }
-
-  public class ViewCompat {
-    ctor @Deprecated protected ViewCompat();
-    method public static int addAccessibilityAction(android.view.View, CharSequence, androidx.core.view.accessibility.AccessibilityViewCommand);
-    method public static void addKeyboardNavigationClusters(android.view.View, java.util.Collection<android.view.View!>, int);
-    method public static void addOnUnhandledKeyEventListener(android.view.View, androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat);
-    method public static androidx.core.view.ViewPropertyAnimatorCompat animate(android.view.View);
-    method @Deprecated public static boolean canScrollHorizontally(android.view.View!, int);
-    method @Deprecated public static boolean canScrollVertically(android.view.View!, int);
-    method public static void cancelDragAndDrop(android.view.View);
-    method @Deprecated public static int combineMeasuredStates(int, int);
-    method public static androidx.core.view.WindowInsetsCompat computeSystemWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat, android.graphics.Rect);
-    method public static androidx.core.view.WindowInsetsCompat dispatchApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
-    method public static void dispatchFinishTemporaryDetach(android.view.View);
-    method public static boolean dispatchNestedFling(android.view.View, float, float, boolean);
-    method public static boolean dispatchNestedPreFling(android.view.View, float, float);
-    method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[]?, int[]?);
-    method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[]?, int[]?, int);
-    method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]?);
-    method public static void dispatchNestedScroll(android.view.View, int, int, int, int, int[]?, int, int[]);
-    method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]?, int);
-    method public static void dispatchStartTemporaryDetach(android.view.View);
-    method public static void enableAccessibleClickableSpanSupport(android.view.View);
-    method public static int generateViewId();
-    method public static androidx.core.view.AccessibilityDelegateCompat? getAccessibilityDelegate(android.view.View);
-    method public static int getAccessibilityLiveRegion(android.view.View);
-    method public static androidx.core.view.accessibility.AccessibilityNodeProviderCompat? getAccessibilityNodeProvider(android.view.View);
-    method @UiThread public static CharSequence? getAccessibilityPaneTitle(android.view.View);
-    method @Deprecated public static float getAlpha(android.view.View!);
-    method public static android.content.res.ColorStateList? getBackgroundTintList(android.view.View);
-    method public static android.graphics.PorterDuff.Mode? getBackgroundTintMode(android.view.View);
-    method public static android.graphics.Rect? getClipBounds(android.view.View);
-    method public static android.view.Display? getDisplay(android.view.View);
-    method public static float getElevation(android.view.View);
-    method public static boolean getFitsSystemWindows(android.view.View);
-    method public static int getImportantForAccessibility(android.view.View);
-    method public static int getImportantForAutofill(android.view.View);
-    method public static int getLabelFor(android.view.View);
-    method @Deprecated public static int getLayerType(android.view.View!);
-    method public static int getLayoutDirection(android.view.View);
-    method @Deprecated public static android.graphics.Matrix? getMatrix(android.view.View!);
-    method @Deprecated public static int getMeasuredHeightAndState(android.view.View!);
-    method @Deprecated public static int getMeasuredState(android.view.View!);
-    method @Deprecated public static int getMeasuredWidthAndState(android.view.View!);
-    method public static int getMinimumHeight(android.view.View);
-    method public static int getMinimumWidth(android.view.View);
-    method public static int getNextClusterForwardId(android.view.View);
-    method public static String![]? getOnReceiveContentMimeTypes(android.view.View);
-    method @Deprecated public static int getOverScrollMode(android.view.View!);
-    method @Px public static int getPaddingEnd(android.view.View);
-    method @Px public static int getPaddingStart(android.view.View);
-    method public static android.view.ViewParent? getParentForAccessibility(android.view.View);
-    method @Deprecated public static float getPivotX(android.view.View!);
-    method @Deprecated public static float getPivotY(android.view.View!);
-    method public static androidx.core.view.WindowInsetsCompat? getRootWindowInsets(android.view.View);
-    method @Deprecated public static float getRotation(android.view.View!);
-    method @Deprecated public static float getRotationX(android.view.View!);
-    method @Deprecated public static float getRotationY(android.view.View!);
-    method @Deprecated public static float getScaleX(android.view.View!);
-    method @Deprecated public static float getScaleY(android.view.View!);
-    method public static int getScrollIndicators(android.view.View);
-    method @UiThread public static CharSequence? getStateDescription(android.view.View);
-    method public static java.util.List<android.graphics.Rect!> getSystemGestureExclusionRects(android.view.View);
-    method public static String? getTransitionName(android.view.View);
-    method @Deprecated public static float getTranslationX(android.view.View!);
-    method @Deprecated public static float getTranslationY(android.view.View!);
-    method public static float getTranslationZ(android.view.View);
-    method @Deprecated public static androidx.core.view.WindowInsetsControllerCompat? getWindowInsetsController(android.view.View);
-    method @Deprecated public static int getWindowSystemUiVisibility(android.view.View);
-    method @Deprecated public static float getX(android.view.View!);
-    method @Deprecated public static float getY(android.view.View!);
-    method public static float getZ(android.view.View);
-    method public static boolean hasAccessibilityDelegate(android.view.View);
-    method public static boolean hasExplicitFocusable(android.view.View);
-    method public static boolean hasNestedScrollingParent(android.view.View);
-    method public static boolean hasNestedScrollingParent(android.view.View, int);
-    method public static boolean hasOnClickListeners(android.view.View);
-    method public static boolean hasOverlappingRendering(android.view.View);
-    method public static boolean hasTransientState(android.view.View);
-    method @UiThread public static boolean isAccessibilityHeading(android.view.View);
-    method public static boolean isAttachedToWindow(android.view.View);
-    method public static boolean isFocusedByDefault(android.view.View);
-    method public static boolean isImportantForAccessibility(android.view.View);
-    method public static boolean isImportantForAutofill(android.view.View);
-    method public static boolean isInLayout(android.view.View);
-    method public static boolean isKeyboardNavigationCluster(android.view.View);
-    method public static boolean isLaidOut(android.view.View);
-    method public static boolean isLayoutDirectionResolved(android.view.View);
-    method public static boolean isNestedScrollingEnabled(android.view.View);
-    method @Deprecated public static boolean isOpaque(android.view.View!);
-    method public static boolean isPaddingRelative(android.view.View);
-    method @UiThread public static boolean isScreenReaderFocusable(android.view.View);
-    method @Deprecated public static void jumpDrawablesToCurrentState(android.view.View!);
-    method public static android.view.View? keyboardNavigationClusterSearch(android.view.View, android.view.View?, int);
-    method public static void offsetLeftAndRight(android.view.View, int);
-    method public static void offsetTopAndBottom(android.view.View, int);
-    method public static androidx.core.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
-    method @Deprecated public static void onInitializeAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
-    method public static void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
-    method @Deprecated public static void onPopulateAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
-    method public static boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
-    method public static androidx.core.view.ContentInfoCompat? performReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
-    method public static void postInvalidateOnAnimation(android.view.View);
-    method public static void postInvalidateOnAnimation(android.view.View, int, int, int, int);
-    method public static void postOnAnimation(android.view.View, Runnable);
-    method public static void postOnAnimationDelayed(android.view.View, Runnable, long);
-    method public static void removeAccessibilityAction(android.view.View, int);
-    method public static void removeOnUnhandledKeyEventListener(android.view.View, androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat);
-    method public static void replaceAccessibilityAction(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat, CharSequence?, androidx.core.view.accessibility.AccessibilityViewCommand?);
-    method public static void requestApplyInsets(android.view.View);
-    method public static <T extends android.view.View> T requireViewById(android.view.View, @IdRes int);
-    method @Deprecated public static int resolveSizeAndState(int, int, int);
-    method public static boolean restoreDefaultFocus(android.view.View);
-    method public static void saveAttributeDataForStyleable(android.view.View, android.content.Context, int[], android.util.AttributeSet?, android.content.res.TypedArray, int, int);
-    method public static void setAccessibilityDelegate(android.view.View, androidx.core.view.AccessibilityDelegateCompat?);
-    method @UiThread public static void setAccessibilityHeading(android.view.View, boolean);
-    method public static void setAccessibilityLiveRegion(android.view.View, int);
-    method @UiThread public static void setAccessibilityPaneTitle(android.view.View, CharSequence?);
-    method @Deprecated public static void setActivated(android.view.View!, boolean);
-    method @Deprecated public static void setAlpha(android.view.View!, @FloatRange(from=0.0, to=1.0) float);
-    method public static void setAutofillHints(android.view.View, java.lang.String!...);
-    method public static void setBackground(android.view.View, android.graphics.drawable.Drawable?);
-    method public static void setBackgroundTintList(android.view.View, android.content.res.ColorStateList?);
-    method public static void setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode?);
-    method @Deprecated public static void setChildrenDrawingOrderEnabled(android.view.ViewGroup!, boolean);
-    method public static void setClipBounds(android.view.View, android.graphics.Rect?);
-    method public static void setElevation(android.view.View, float);
-    method @Deprecated public static void setFitsSystemWindows(android.view.View!, boolean);
-    method public static void setFocusedByDefault(android.view.View, boolean);
-    method public static void setHasTransientState(android.view.View, boolean);
-    method @UiThread public static void setImportantForAccessibility(android.view.View, int);
-    method public static void setImportantForAutofill(android.view.View, int);
-    method public static void setKeyboardNavigationCluster(android.view.View, boolean);
-    method public static void setLabelFor(android.view.View, @IdRes int);
-    method public static void setLayerPaint(android.view.View, android.graphics.Paint?);
-    method @Deprecated public static void setLayerType(android.view.View!, int, android.graphics.Paint!);
-    method public static void setLayoutDirection(android.view.View, int);
-    method public static void setNestedScrollingEnabled(android.view.View, boolean);
-    method public static void setNextClusterForwardId(android.view.View, int);
-    method public static void setOnApplyWindowInsetsListener(android.view.View, androidx.core.view.OnApplyWindowInsetsListener?);
-    method public static void setOnReceiveContentListener(android.view.View, String![]?, androidx.core.view.OnReceiveContentListener?);
-    method @Deprecated public static void setOverScrollMode(android.view.View!, int);
-    method public static void setPaddingRelative(android.view.View, @Px int, @Px int, @Px int, @Px int);
-    method @Deprecated public static void setPivotX(android.view.View!, float);
-    method @Deprecated public static void setPivotY(android.view.View!, float);
-    method public static void setPointerIcon(android.view.View, androidx.core.view.PointerIconCompat?);
-    method @Deprecated public static void setRotation(android.view.View!, float);
-    method @Deprecated public static void setRotationX(android.view.View!, float);
-    method @Deprecated public static void setRotationY(android.view.View!, float);
-    method @Deprecated public static void setSaveFromParentEnabled(android.view.View!, boolean);
-    method @Deprecated public static void setScaleX(android.view.View!, float);
-    method @Deprecated public static void setScaleY(android.view.View!, float);
-    method @UiThread public static void setScreenReaderFocusable(android.view.View, boolean);
-    method public static void setScrollIndicators(android.view.View, int);
-    method public static void setScrollIndicators(android.view.View, int, int);
-    method @UiThread public static void setStateDescription(android.view.View, CharSequence?);
-    method public static void setSystemGestureExclusionRects(android.view.View, java.util.List<android.graphics.Rect!>);
-    method public static void setTooltipText(android.view.View, CharSequence?);
-    method public static void setTransitionName(android.view.View, String?);
-    method @Deprecated public static void setTranslationX(android.view.View!, float);
-    method @Deprecated public static void setTranslationY(android.view.View!, float);
-    method public static void setTranslationZ(android.view.View, float);
-    method public static void setWindowInsetsAnimationCallback(android.view.View, androidx.core.view.WindowInsetsAnimationCompat.Callback?);
-    method @Deprecated public static void setX(android.view.View!, float);
-    method @Deprecated public static void setY(android.view.View!, float);
-    method public static void setZ(android.view.View, float);
-    method public static boolean startDragAndDrop(android.view.View, android.content.ClipData?, android.view.View.DragShadowBuilder, Object?, int);
-    method public static boolean startNestedScroll(android.view.View, int);
-    method public static boolean startNestedScroll(android.view.View, int, int);
-    method public static void stopNestedScroll(android.view.View);
-    method public static void stopNestedScroll(android.view.View, int);
-    method public static void updateDragShadow(android.view.View, android.view.View.DragShadowBuilder);
-    field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
-    field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
-    field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
-    field public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0; // 0x0
-    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 2; // 0x2
-    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 4; // 0x4
-    field public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 1; // 0x1
-    field @Deprecated public static final int LAYER_TYPE_HARDWARE = 2; // 0x2
-    field @Deprecated public static final int LAYER_TYPE_NONE = 0; // 0x0
-    field @Deprecated public static final int LAYER_TYPE_SOFTWARE = 1; // 0x1
-    field public static final int LAYOUT_DIRECTION_INHERIT = 2; // 0x2
-    field public static final int LAYOUT_DIRECTION_LOCALE = 3; // 0x3
-    field public static final int LAYOUT_DIRECTION_LTR = 0; // 0x0
-    field public static final int LAYOUT_DIRECTION_RTL = 1; // 0x1
-    field @Deprecated public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
-    field @Deprecated public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
-    field @Deprecated public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
-    field @Deprecated public static final int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
-    field @Deprecated public static final int OVER_SCROLL_ALWAYS = 0; // 0x0
-    field @Deprecated public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; // 0x1
-    field @Deprecated public static final int OVER_SCROLL_NEVER = 2; // 0x2
-    field public static final int SCROLL_AXIS_HORIZONTAL = 1; // 0x1
-    field public static final int SCROLL_AXIS_NONE = 0; // 0x0
-    field public static final int SCROLL_AXIS_VERTICAL = 2; // 0x2
-    field public static final int SCROLL_INDICATOR_BOTTOM = 2; // 0x2
-    field public static final int SCROLL_INDICATOR_END = 32; // 0x20
-    field public static final int SCROLL_INDICATOR_LEFT = 4; // 0x4
-    field public static final int SCROLL_INDICATOR_RIGHT = 8; // 0x8
-    field public static final int SCROLL_INDICATOR_START = 16; // 0x10
-    field public static final int SCROLL_INDICATOR_TOP = 1; // 0x1
-    field public static final int TYPE_NON_TOUCH = 1; // 0x1
-    field public static final int TYPE_TOUCH = 0; // 0x0
-  }
-
-  public static interface ViewCompat.OnUnhandledKeyEventListenerCompat {
-    method public boolean onUnhandledKeyEvent(android.view.View, android.view.KeyEvent);
-  }
-
-  public final class ViewConfigurationCompat {
-    method public static float getScaledHorizontalScrollFactor(android.view.ViewConfiguration, android.content.Context);
-    method public static int getScaledHoverSlop(android.view.ViewConfiguration);
-    method @Deprecated public static int getScaledPagingTouchSlop(android.view.ViewConfiguration!);
-    method public static float getScaledVerticalScrollFactor(android.view.ViewConfiguration, android.content.Context);
-    method @Deprecated public static boolean hasPermanentMenuKey(android.view.ViewConfiguration!);
-    method public static boolean shouldShowMenuShortcutsWhenKeyboardPresent(android.view.ViewConfiguration, android.content.Context);
-  }
-
-  public final class ViewGroupCompat {
-    method public static int getLayoutMode(android.view.ViewGroup);
-    method public static int getNestedScrollAxes(android.view.ViewGroup);
-    method public static boolean isTransitionGroup(android.view.ViewGroup);
-    method @Deprecated public static boolean onRequestSendAccessibilityEvent(android.view.ViewGroup!, android.view.View!, android.view.accessibility.AccessibilityEvent!);
-    method public static void setLayoutMode(android.view.ViewGroup, int);
-    method @Deprecated public static void setMotionEventSplittingEnabled(android.view.ViewGroup!, boolean);
-    method public static void setTransitionGroup(android.view.ViewGroup, boolean);
-    field public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; // 0x0
-    field public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; // 0x1
-  }
-
-  public final class ViewParentCompat {
-    method public static void notifySubtreeAccessibilityStateChanged(android.view.ViewParent, android.view.View, android.view.View, int);
-    method public static boolean onNestedFling(android.view.ViewParent, android.view.View, float, float, boolean);
-    method public static boolean onNestedPreFling(android.view.ViewParent, android.view.View, float, float);
-    method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[]);
-    method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[], int);
-    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int);
-    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int);
-    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int, int[]);
-    method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int);
-    method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int, int);
-    method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int);
-    method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int, int);
-    method public static void onStopNestedScroll(android.view.ViewParent, android.view.View);
-    method public static void onStopNestedScroll(android.view.ViewParent, android.view.View, int);
-    method @Deprecated public static boolean requestSendAccessibilityEvent(android.view.ViewParent!, android.view.View!, android.view.accessibility.AccessibilityEvent!);
-  }
-
-  public final class ViewPropertyAnimatorCompat {
-    method public androidx.core.view.ViewPropertyAnimatorCompat alpha(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat alphaBy(float);
-    method public void cancel();
-    method public long getDuration();
-    method public android.view.animation.Interpolator? getInterpolator();
-    method public long getStartDelay();
-    method public androidx.core.view.ViewPropertyAnimatorCompat rotation(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat rotationBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat rotationX(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat rotationXBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat rotationY(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat rotationYBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat scaleX(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat scaleXBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat scaleY(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat scaleYBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat setDuration(long);
-    method public androidx.core.view.ViewPropertyAnimatorCompat setInterpolator(android.view.animation.Interpolator?);
-    method public androidx.core.view.ViewPropertyAnimatorCompat setListener(androidx.core.view.ViewPropertyAnimatorListener?);
-    method public androidx.core.view.ViewPropertyAnimatorCompat setStartDelay(long);
-    method public androidx.core.view.ViewPropertyAnimatorCompat setUpdateListener(androidx.core.view.ViewPropertyAnimatorUpdateListener?);
-    method public void start();
-    method public androidx.core.view.ViewPropertyAnimatorCompat translationX(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat translationXBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat translationY(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat translationYBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat translationZ(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat translationZBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat withEndAction(Runnable);
-    method public androidx.core.view.ViewPropertyAnimatorCompat withLayer();
-    method public androidx.core.view.ViewPropertyAnimatorCompat withStartAction(Runnable);
-    method public androidx.core.view.ViewPropertyAnimatorCompat x(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat xBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat y(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat yBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat z(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat zBy(float);
-  }
-
-  public interface ViewPropertyAnimatorListener {
-    method public void onAnimationCancel(android.view.View);
-    method public void onAnimationEnd(android.view.View);
-    method public void onAnimationStart(android.view.View);
-  }
-
-  public class ViewPropertyAnimatorListenerAdapter implements androidx.core.view.ViewPropertyAnimatorListener {
-    ctor public ViewPropertyAnimatorListenerAdapter();
-    method public void onAnimationCancel(android.view.View);
-    method public void onAnimationEnd(android.view.View);
-    method public void onAnimationStart(android.view.View);
-  }
-
-  public interface ViewPropertyAnimatorUpdateListener {
-    method public void onAnimationUpdate(android.view.View);
-  }
-
-  public final class WindowCompat {
-    method public static androidx.core.view.WindowInsetsControllerCompat getInsetsController(android.view.Window, android.view.View);
-    method public static <T extends android.view.View> T requireViewById(android.view.Window, @IdRes int);
-    method public static void setDecorFitsSystemWindows(android.view.Window, boolean);
-    field public static final int FEATURE_ACTION_BAR = 8; // 0x8
-    field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
-    field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
-  }
-
-  public final class WindowInsetsAnimationCompat {
-    ctor public WindowInsetsAnimationCompat(int, android.view.animation.Interpolator?, long);
-    method @FloatRange(from=0.0f, to=1.0f) public float getAlpha();
-    method public long getDurationMillis();
-    method @FloatRange(from=0.0f, to=1.0f) public float getFraction();
-    method public float getInterpolatedFraction();
-    method public android.view.animation.Interpolator? getInterpolator();
-    method public int getTypeMask();
-    method public void setAlpha(@FloatRange(from=0.0f, to=1.0f) float);
-    method public void setFraction(@FloatRange(from=0.0f, to=1.0f) float);
-  }
-
-  public static final class WindowInsetsAnimationCompat.BoundsCompat {
-    ctor public WindowInsetsAnimationCompat.BoundsCompat(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
-    method public androidx.core.graphics.Insets getLowerBound();
-    method public androidx.core.graphics.Insets getUpperBound();
-    method public androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat inset(androidx.core.graphics.Insets);
-    method @RequiresApi(30) public android.view.WindowInsetsAnimation.Bounds toBounds();
-    method @RequiresApi(30) public static androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat toBoundsCompat(android.view.WindowInsetsAnimation.Bounds);
-  }
-
-  public abstract static class WindowInsetsAnimationCompat.Callback {
-    ctor public WindowInsetsAnimationCompat.Callback(int);
-    method public final int getDispatchMode();
-    method public void onEnd(androidx.core.view.WindowInsetsAnimationCompat);
-    method public void onPrepare(androidx.core.view.WindowInsetsAnimationCompat);
-    method public abstract androidx.core.view.WindowInsetsCompat onProgress(androidx.core.view.WindowInsetsCompat, java.util.List<androidx.core.view.WindowInsetsAnimationCompat!>);
-    method public androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat onStart(androidx.core.view.WindowInsetsAnimationCompat, androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat);
-    field public static final int DISPATCH_MODE_CONTINUE_ON_SUBTREE = 1; // 0x1
-    field public static final int DISPATCH_MODE_STOP = 0; // 0x0
-  }
-
-  public interface WindowInsetsAnimationControlListenerCompat {
-    method public void onCancelled(androidx.core.view.WindowInsetsAnimationControllerCompat?);
-    method public void onFinished(androidx.core.view.WindowInsetsAnimationControllerCompat);
-    method public void onReady(androidx.core.view.WindowInsetsAnimationControllerCompat, int);
-  }
-
-  public final class WindowInsetsAnimationControllerCompat {
-    method public void finish(boolean);
-    method public float getCurrentAlpha();
-    method @FloatRange(from=0.0f, to=1.0f) public float getCurrentFraction();
-    method public androidx.core.graphics.Insets getCurrentInsets();
-    method public androidx.core.graphics.Insets getHiddenStateInsets();
-    method public androidx.core.graphics.Insets getShownStateInsets();
-    method public int getTypes();
-    method public boolean isCancelled();
-    method public boolean isFinished();
-    method public boolean isReady();
-    method public void setInsetsAndAlpha(androidx.core.graphics.Insets?, @FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float);
-  }
-
-  public class WindowInsetsCompat {
-    ctor public WindowInsetsCompat(androidx.core.view.WindowInsetsCompat?);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeDisplayCutout();
-    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeStableInsets();
-    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeSystemWindowInsets();
-    method public androidx.core.view.DisplayCutoutCompat? getDisplayCutout();
-    method public androidx.core.graphics.Insets getInsets(int);
-    method public androidx.core.graphics.Insets getInsetsIgnoringVisibility(int);
-    method @Deprecated public androidx.core.graphics.Insets getMandatorySystemGestureInsets();
-    method @Deprecated public int getStableInsetBottom();
-    method @Deprecated public int getStableInsetLeft();
-    method @Deprecated public int getStableInsetRight();
-    method @Deprecated public int getStableInsetTop();
-    method @Deprecated public androidx.core.graphics.Insets getStableInsets();
-    method @Deprecated public androidx.core.graphics.Insets getSystemGestureInsets();
-    method @Deprecated public int getSystemWindowInsetBottom();
-    method @Deprecated public int getSystemWindowInsetLeft();
-    method @Deprecated public int getSystemWindowInsetRight();
-    method @Deprecated public int getSystemWindowInsetTop();
-    method @Deprecated public androidx.core.graphics.Insets getSystemWindowInsets();
-    method @Deprecated public androidx.core.graphics.Insets getTappableElementInsets();
-    method public boolean hasInsets();
-    method @Deprecated public boolean hasStableInsets();
-    method @Deprecated public boolean hasSystemWindowInsets();
-    method public androidx.core.view.WindowInsetsCompat inset(androidx.core.graphics.Insets);
-    method public androidx.core.view.WindowInsetsCompat inset(@IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int);
-    method public boolean isConsumed();
-    method public boolean isRound();
-    method public boolean isVisible(int);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat replaceSystemWindowInsets(int, int, int, int);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat replaceSystemWindowInsets(android.graphics.Rect);
-    method @RequiresApi(20) public android.view.WindowInsets? toWindowInsets();
-    method @RequiresApi(20) public static androidx.core.view.WindowInsetsCompat toWindowInsetsCompat(android.view.WindowInsets);
-    method @RequiresApi(20) public static androidx.core.view.WindowInsetsCompat toWindowInsetsCompat(android.view.WindowInsets, android.view.View?);
-    field public static final androidx.core.view.WindowInsetsCompat CONSUMED;
-  }
-
-  public static final class WindowInsetsCompat.Builder {
-    ctor public WindowInsetsCompat.Builder();
-    ctor public WindowInsetsCompat.Builder(androidx.core.view.WindowInsetsCompat);
-    method public androidx.core.view.WindowInsetsCompat build();
-    method public androidx.core.view.WindowInsetsCompat.Builder setDisplayCutout(androidx.core.view.DisplayCutoutCompat?);
-    method public androidx.core.view.WindowInsetsCompat.Builder setInsets(int, androidx.core.graphics.Insets);
-    method public androidx.core.view.WindowInsetsCompat.Builder setInsetsIgnoringVisibility(int, androidx.core.graphics.Insets);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setMandatorySystemGestureInsets(androidx.core.graphics.Insets);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setStableInsets(androidx.core.graphics.Insets);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setSystemGestureInsets(androidx.core.graphics.Insets);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setSystemWindowInsets(androidx.core.graphics.Insets);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setTappableElementInsets(androidx.core.graphics.Insets);
-    method public androidx.core.view.WindowInsetsCompat.Builder setVisible(int, boolean);
-  }
-
-  public static final class WindowInsetsCompat.Type {
-    method public static int captionBar();
-    method public static int displayCutout();
-    method public static int ime();
-    method public static int mandatorySystemGestures();
-    method public static int navigationBars();
-    method public static int statusBars();
-    method public static int systemBars();
-    method public static int systemGestures();
-    method public static int tappableElement();
-  }
-
-  public final class WindowInsetsControllerCompat {
-    ctor public WindowInsetsControllerCompat(android.view.Window, android.view.View);
-    method public void addOnControllableInsetsChangedListener(androidx.core.view.WindowInsetsControllerCompat.OnControllableInsetsChangedListener);
-    method public void controlWindowInsetsAnimation(int, long, android.view.animation.Interpolator?, android.os.CancellationSignal?, androidx.core.view.WindowInsetsAnimationControlListenerCompat);
-    method public int getSystemBarsBehavior();
-    method public void hide(int);
-    method public boolean isAppearanceLightNavigationBars();
-    method public boolean isAppearanceLightStatusBars();
-    method public void removeOnControllableInsetsChangedListener(androidx.core.view.WindowInsetsControllerCompat.OnControllableInsetsChangedListener);
-    method public void setAppearanceLightNavigationBars(boolean);
-    method public void setAppearanceLightStatusBars(boolean);
-    method public void setSystemBarsBehavior(int);
-    method public void show(int);
-    method @Deprecated @RequiresApi(30) public static androidx.core.view.WindowInsetsControllerCompat toWindowInsetsControllerCompat(android.view.WindowInsetsController);
-    field public static final int BEHAVIOR_SHOW_BARS_BY_SWIPE = 1; // 0x1
-    field public static final int BEHAVIOR_SHOW_BARS_BY_TOUCH = 0; // 0x0
-    field public static final int BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE = 2; // 0x2
-  }
-
-  public static interface WindowInsetsControllerCompat.OnControllableInsetsChangedListener {
-    method public void onControllableInsetsChanged(androidx.core.view.WindowInsetsControllerCompat, int);
-  }
-
-}
-
-package androidx.core.view.accessibility {
-
-  public final class AccessibilityClickableSpanCompat extends android.text.style.ClickableSpan {
-    method public void onClick(android.view.View);
-  }
-
-  public final class AccessibilityEventCompat {
-    method @Deprecated public static void appendRecord(android.view.accessibility.AccessibilityEvent!, androidx.core.view.accessibility.AccessibilityRecordCompat!);
-    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! asRecord(android.view.accessibility.AccessibilityEvent!);
-    method public static int getAction(android.view.accessibility.AccessibilityEvent);
-    method public static int getContentChangeTypes(android.view.accessibility.AccessibilityEvent);
-    method public static int getMovementGranularity(android.view.accessibility.AccessibilityEvent);
-    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! getRecord(android.view.accessibility.AccessibilityEvent!, int);
-    method @Deprecated public static int getRecordCount(android.view.accessibility.AccessibilityEvent!);
-    method public static void setAction(android.view.accessibility.AccessibilityEvent, int);
-    method public static void setContentChangeTypes(android.view.accessibility.AccessibilityEvent, int);
-    method public static void setMovementGranularity(android.view.accessibility.AccessibilityEvent, int);
-    field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
-    field public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 16; // 0x10
-    field public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 32; // 0x20
-    field public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 8; // 0x8
-    field public static final int CONTENT_CHANGE_TYPE_STATE_DESCRIPTION = 64; // 0x40
-    field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
-    field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2
-    field public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0; // 0x0
-    field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
-    field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
-    field public static final int TYPE_ASSIST_READING_CONTEXT = 16777216; // 0x1000000
-    field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000
-    field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000
-    field @Deprecated public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400
-    field @Deprecated public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200
-    field public static final int TYPE_TOUCH_INTERACTION_END = 2097152; // 0x200000
-    field public static final int TYPE_TOUCH_INTERACTION_START = 1048576; // 0x100000
-    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 32768; // 0x8000
-    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 65536; // 0x10000
-    field public static final int TYPE_VIEW_CONTEXT_CLICKED = 8388608; // 0x800000
-    field @Deprecated public static final int TYPE_VIEW_HOVER_ENTER = 128; // 0x80
-    field @Deprecated public static final int TYPE_VIEW_HOVER_EXIT = 256; // 0x100
-    field @Deprecated public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
-    field @Deprecated public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
-    field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
-    field public static final int TYPE_WINDOWS_CHANGED = 4194304; // 0x400000
-    field @Deprecated public static final int TYPE_WINDOW_CONTENT_CHANGED = 2048; // 0x800
-  }
-
-  public final class AccessibilityManagerCompat {
-    method @Deprecated public static boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager!, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener!);
-    method public static boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
-    method @Deprecated public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo!>! getEnabledAccessibilityServiceList(android.view.accessibility.AccessibilityManager!, int);
-    method @Deprecated public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo!>! getInstalledAccessibilityServiceList(android.view.accessibility.AccessibilityManager!);
-    method @Deprecated public static boolean isTouchExplorationEnabled(android.view.accessibility.AccessibilityManager!);
-    method @Deprecated public static boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager!, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener!);
-    method public static boolean removeTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
-  }
-
-  @Deprecated public static interface AccessibilityManagerCompat.AccessibilityStateChangeListener {
-    method @Deprecated public void onAccessibilityStateChanged(boolean);
-  }
-
-  @Deprecated public abstract static class AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat implements androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener {
-    ctor @Deprecated public AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat();
-  }
-
-  public static interface AccessibilityManagerCompat.TouchExplorationStateChangeListener {
-    method public void onTouchExplorationStateChanged(boolean);
-  }
-
-  public class AccessibilityNodeInfoCompat {
-    ctor @Deprecated public AccessibilityNodeInfoCompat(Object!);
-    method public void addAction(int);
-    method public void addAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!);
-    method public void addChild(android.view.View!);
-    method public void addChild(android.view.View!, int);
-    method public boolean canOpenPopup();
-    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>! findAccessibilityNodeInfosByText(String!);
-    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>! findAccessibilityNodeInfosByViewId(String!);
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! findFocus(int);
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! focusSearch(int);
-    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!>! getActionList();
-    method public int getActions();
-    method public java.util.List<java.lang.String!> getAvailableExtraData();
-    method @Deprecated public void getBoundsInParent(android.graphics.Rect!);
-    method public void getBoundsInScreen(android.graphics.Rect!);
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getChild(int);
-    method public int getChildCount();
-    method public CharSequence! getClassName();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! getCollectionInfo();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! getCollectionItemInfo();
-    method public CharSequence! getContentDescription();
-    method public int getDrawingOrder();
-    method public CharSequence! getError();
-    method public android.os.Bundle! getExtras();
-    method public CharSequence? getHintText();
-    method @Deprecated public Object! getInfo();
-    method public int getInputType();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabelFor();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabeledBy();
-    method public int getLiveRegion();
-    method public int getMaxTextLength();
-    method public int getMovementGranularities();
-    method public CharSequence! getPackageName();
-    method public CharSequence? getPaneTitle();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getParent();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat! getRangeInfo();
-    method public CharSequence? getRoleDescription();
-    method public CharSequence? getStateDescription();
-    method public CharSequence! getText();
-    method public int getTextSelectionEnd();
-    method public int getTextSelectionStart();
-    method public CharSequence? getTooltipText();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat? getTouchDelegateInfo();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalAfter();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalBefore();
-    method public String! getViewIdResourceName();
-    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat! getWindow();
-    method public int getWindowId();
-    method public boolean isAccessibilityFocused();
-    method public boolean isCheckable();
-    method public boolean isChecked();
-    method public boolean isClickable();
-    method public boolean isContentInvalid();
-    method public boolean isContextClickable();
-    method public boolean isDismissable();
-    method public boolean isEditable();
-    method public boolean isEnabled();
-    method public boolean isFocusable();
-    method public boolean isFocused();
-    method public boolean isHeading();
-    method public boolean isImportantForAccessibility();
-    method public boolean isLongClickable();
-    method public boolean isMultiLine();
-    method public boolean isPassword();
-    method public boolean isScreenReaderFocusable();
-    method public boolean isScrollable();
-    method public boolean isSelected();
-    method public boolean isShowingHintText();
-    method public boolean isTextEntryKey();
-    method public boolean isVisibleToUser();
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!);
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!, int);
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain();
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(androidx.core.view.accessibility.AccessibilityNodeInfoCompat!);
-    method public boolean performAction(int);
-    method public boolean performAction(int, android.os.Bundle!);
-    method public void recycle();
-    method public boolean refresh();
-    method public boolean removeAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!);
-    method public boolean removeChild(android.view.View!);
-    method public boolean removeChild(android.view.View!, int);
-    method public void setAccessibilityFocused(boolean);
-    method public void setAvailableExtraData(java.util.List<java.lang.String!>);
-    method @Deprecated public void setBoundsInParent(android.graphics.Rect!);
-    method public void setBoundsInScreen(android.graphics.Rect!);
-    method public void setCanOpenPopup(boolean);
-    method public void setCheckable(boolean);
-    method public void setChecked(boolean);
-    method public void setClassName(CharSequence!);
-    method public void setClickable(boolean);
-    method public void setCollectionInfo(Object!);
-    method public void setCollectionItemInfo(Object!);
-    method public void setContentDescription(CharSequence!);
-    method public void setContentInvalid(boolean);
-    method public void setContextClickable(boolean);
-    method public void setDismissable(boolean);
-    method public void setDrawingOrder(int);
-    method public void setEditable(boolean);
-    method public void setEnabled(boolean);
-    method public void setError(CharSequence!);
-    method public void setFocusable(boolean);
-    method public void setFocused(boolean);
-    method public void setHeading(boolean);
-    method public void setHintText(CharSequence?);
-    method public void setImportantForAccessibility(boolean);
-    method public void setInputType(int);
-    method public void setLabelFor(android.view.View!);
-    method public void setLabelFor(android.view.View!, int);
-    method public void setLabeledBy(android.view.View!);
-    method public void setLabeledBy(android.view.View!, int);
-    method public void setLiveRegion(int);
-    method public void setLongClickable(boolean);
-    method public void setMaxTextLength(int);
-    method public void setMovementGranularities(int);
-    method public void setMultiLine(boolean);
-    method public void setPackageName(CharSequence!);
-    method public void setPaneTitle(CharSequence?);
-    method public void setParent(android.view.View!);
-    method public void setParent(android.view.View!, int);
-    method public void setPassword(boolean);
-    method public void setRangeInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat!);
-    method public void setRoleDescription(CharSequence?);
-    method public void setScreenReaderFocusable(boolean);
-    method public void setScrollable(boolean);
-    method public void setSelected(boolean);
-    method public void setShowingHintText(boolean);
-    method public void setSource(android.view.View!);
-    method public void setSource(android.view.View!, int);
-    method public void setStateDescription(CharSequence?);
-    method public void setText(CharSequence!);
-    method public void setTextEntryKey(boolean);
-    method public void setTextSelection(int, int);
-    method public void setTooltipText(CharSequence?);
-    method public void setTouchDelegateInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat);
-    method public void setTraversalAfter(android.view.View!);
-    method public void setTraversalAfter(android.view.View!, int);
-    method public void setTraversalBefore(android.view.View!);
-    method public void setTraversalBefore(android.view.View!, int);
-    method public void setViewIdResourceName(String!);
-    method public void setVisibleToUser(boolean);
-    method public android.view.accessibility.AccessibilityNodeInfo! unwrap();
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! wrap(android.view.accessibility.AccessibilityNodeInfo);
-    field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
-    field public static final String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT";
-    field public static final String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
-    field public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
-    field public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
-    field public static final String ACTION_ARGUMENT_MOVE_WINDOW_X = "ACTION_ARGUMENT_MOVE_WINDOW_X";
-    field public static final String ACTION_ARGUMENT_MOVE_WINDOW_Y = "ACTION_ARGUMENT_MOVE_WINDOW_Y";
-    field public static final String ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT = "android.view.accessibility.action.ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT";
-    field public static final String ACTION_ARGUMENT_PROGRESS_VALUE = "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
-    field public static final String ACTION_ARGUMENT_ROW_INT = "android.view.accessibility.action.ARGUMENT_ROW_INT";
-    field public static final String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
-    field public static final String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
-    field public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
-    field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
-    field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
-    field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
-    field public static final int ACTION_CLICK = 16; // 0x10
-    field public static final int ACTION_COLLAPSE = 524288; // 0x80000
-    field public static final int ACTION_COPY = 16384; // 0x4000
-    field public static final int ACTION_CUT = 65536; // 0x10000
-    field public static final int ACTION_DISMISS = 1048576; // 0x100000
-    field public static final int ACTION_EXPAND = 262144; // 0x40000
-    field public static final int ACTION_FOCUS = 1; // 0x1
-    field public static final int ACTION_LONG_CLICK = 32; // 0x20
-    field public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 256; // 0x100
-    field public static final int ACTION_NEXT_HTML_ELEMENT = 1024; // 0x400
-    field public static final int ACTION_PASTE = 32768; // 0x8000
-    field public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 512; // 0x200
-    field public static final int ACTION_PREVIOUS_HTML_ELEMENT = 2048; // 0x800
-    field public static final int ACTION_SCROLL_BACKWARD = 8192; // 0x2000
-    field public static final int ACTION_SCROLL_FORWARD = 4096; // 0x1000
-    field public static final int ACTION_SELECT = 4; // 0x4
-    field public static final int ACTION_SET_SELECTION = 131072; // 0x20000
-    field public static final int ACTION_SET_TEXT = 2097152; // 0x200000
-    field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
-    field public static final int FOCUS_INPUT = 1; // 0x1
-    field public static final int MOVEMENT_GRANULARITY_CHARACTER = 1; // 0x1
-    field public static final int MOVEMENT_GRANULARITY_LINE = 4; // 0x4
-    field public static final int MOVEMENT_GRANULARITY_PAGE = 16; // 0x10
-    field public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 8; // 0x8
-    field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
-  }
-
-  public static class AccessibilityNodeInfoCompat.AccessibilityActionCompat {
-    ctor public AccessibilityNodeInfoCompat.AccessibilityActionCompat(int, CharSequence!);
-    method public int getId();
-    method public CharSequence! getLabel();
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_ACCESSIBILITY_FOCUS;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_ACCESSIBILITY_FOCUS;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_FOCUS;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_SELECTION;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLICK;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COLLAPSE;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CONTEXT_CLICK;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COPY;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CUT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_DISMISS;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_EXPAND;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_FOCUS;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_HIDE_TOOLTIP;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_IME_ENTER;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_LONG_CLICK;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_MOVE_WINDOW;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_HTML_ELEMENT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_DOWN;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_LEFT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_RIGHT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_UP;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PASTE;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PRESS_AND_HOLD;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_HTML_ELEMENT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_BACKWARD;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_DOWN;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_FORWARD;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_LEFT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_RIGHT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_TO_POSITION;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_UP;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SELECT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_PROGRESS;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_SELECTION;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_TEXT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SHOW_ON_SCREEN;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SHOW_TOOLTIP;
-  }
-
-  public static class AccessibilityNodeInfoCompat.CollectionInfoCompat {
-    method public int getColumnCount();
-    method public int getRowCount();
-    method public int getSelectionMode();
-    method public boolean isHierarchical();
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! obtain(int, int, boolean, int);
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! obtain(int, int, boolean);
-    field public static final int SELECTION_MODE_MULTIPLE = 2; // 0x2
-    field public static final int SELECTION_MODE_NONE = 0; // 0x0
-    field public static final int SELECTION_MODE_SINGLE = 1; // 0x1
-  }
-
-  public static class AccessibilityNodeInfoCompat.CollectionItemInfoCompat {
-    method public int getColumnIndex();
-    method public int getColumnSpan();
-    method public int getRowIndex();
-    method public int getRowSpan();
-    method @Deprecated public boolean isHeading();
-    method public boolean isSelected();
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! obtain(int, int, int, int, boolean, boolean);
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! obtain(int, int, int, int, boolean);
-  }
-
-  public static class AccessibilityNodeInfoCompat.RangeInfoCompat {
-    method public float getCurrent();
-    method public float getMax();
-    method public float getMin();
-    method public int getType();
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat! obtain(int, float, float, float);
-    field public static final int RANGE_TYPE_FLOAT = 1; // 0x1
-    field public static final int RANGE_TYPE_INT = 0; // 0x0
-    field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
-  }
-
-  public static final class AccessibilityNodeInfoCompat.TouchDelegateInfoCompat {
-    ctor public AccessibilityNodeInfoCompat.TouchDelegateInfoCompat(java.util.Map<android.graphics.Region!,android.view.View!>);
-    method public android.graphics.Region? getRegionAt(@IntRange(from=0) int);
-    method @IntRange(from=0) public int getRegionCount();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getTargetForRegion(android.graphics.Region);
-  }
-
-  public class AccessibilityNodeProviderCompat {
-    ctor public AccessibilityNodeProviderCompat();
-    ctor public AccessibilityNodeProviderCompat(Object?);
-    method public void addExtraDataToAccessibilityNodeInfo(int, androidx.core.view.accessibility.AccessibilityNodeInfoCompat, String, android.os.Bundle?);
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? createAccessibilityNodeInfo(int);
-    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>? findAccessibilityNodeInfosByText(String, int);
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? findFocus(int);
-    method public Object? getProvider();
-    method public boolean performAction(int, int, android.os.Bundle?);
-    field public static final int HOST_VIEW_ID = -1; // 0xffffffff
-  }
-
-  public class AccessibilityRecordCompat {
-    ctor @Deprecated public AccessibilityRecordCompat(Object!);
-    method @Deprecated public boolean equals(Object?);
-    method @Deprecated public int getAddedCount();
-    method @Deprecated public CharSequence! getBeforeText();
-    method @Deprecated public CharSequence! getClassName();
-    method @Deprecated public CharSequence! getContentDescription();
-    method @Deprecated public int getCurrentItemIndex();
-    method @Deprecated public int getFromIndex();
-    method @Deprecated public Object! getImpl();
-    method @Deprecated public int getItemCount();
-    method @Deprecated public int getMaxScrollX();
-    method public static int getMaxScrollX(android.view.accessibility.AccessibilityRecord);
-    method @Deprecated public int getMaxScrollY();
-    method public static int getMaxScrollY(android.view.accessibility.AccessibilityRecord);
-    method @Deprecated public android.os.Parcelable! getParcelableData();
-    method @Deprecated public int getRemovedCount();
-    method @Deprecated public int getScrollX();
-    method @Deprecated public int getScrollY();
-    method @Deprecated public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getSource();
-    method @Deprecated public java.util.List<java.lang.CharSequence!>! getText();
-    method @Deprecated public int getToIndex();
-    method @Deprecated public int getWindowId();
-    method @Deprecated public int hashCode();
-    method @Deprecated public boolean isChecked();
-    method @Deprecated public boolean isEnabled();
-    method @Deprecated public boolean isFullScreen();
-    method @Deprecated public boolean isPassword();
-    method @Deprecated public boolean isScrollable();
-    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! obtain(androidx.core.view.accessibility.AccessibilityRecordCompat!);
-    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! obtain();
-    method @Deprecated public void recycle();
-    method @Deprecated public void setAddedCount(int);
-    method @Deprecated public void setBeforeText(CharSequence!);
-    method @Deprecated public void setChecked(boolean);
-    method @Deprecated public void setClassName(CharSequence!);
-    method @Deprecated public void setContentDescription(CharSequence!);
-    method @Deprecated public void setCurrentItemIndex(int);
-    method @Deprecated public void setEnabled(boolean);
-    method @Deprecated public void setFromIndex(int);
-    method @Deprecated public void setFullScreen(boolean);
-    method @Deprecated public void setItemCount(int);
-    method @Deprecated public void setMaxScrollX(int);
-    method public static void setMaxScrollX(android.view.accessibility.AccessibilityRecord, int);
-    method @Deprecated public void setMaxScrollY(int);
-    method public static void setMaxScrollY(android.view.accessibility.AccessibilityRecord, int);
-    method @Deprecated public void setParcelableData(android.os.Parcelable!);
-    method @Deprecated public void setPassword(boolean);
-    method @Deprecated public void setRemovedCount(int);
-    method @Deprecated public void setScrollX(int);
-    method @Deprecated public void setScrollY(int);
-    method @Deprecated public void setScrollable(boolean);
-    method @Deprecated public void setSource(android.view.View!);
-    method @Deprecated public void setSource(android.view.View!, int);
-    method public static void setSource(android.view.accessibility.AccessibilityRecord, android.view.View?, int);
-    method @Deprecated public void setToIndex(int);
-  }
-
-  public interface AccessibilityViewCommand {
-    method public boolean perform(android.view.View, androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments?);
-  }
-
-  public abstract static class AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.CommandArguments();
-  }
-
-  public static final class AccessibilityViewCommand.MoveAtGranularityArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.MoveAtGranularityArguments();
-    method public boolean getExtendSelection();
-    method public int getGranularity();
-  }
-
-  public static final class AccessibilityViewCommand.MoveHtmlArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.MoveHtmlArguments();
-    method public String? getHTMLElement();
-  }
-
-  public static final class AccessibilityViewCommand.MoveWindowArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.MoveWindowArguments();
-    method public int getX();
-    method public int getY();
-  }
-
-  public static final class AccessibilityViewCommand.ScrollToPositionArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.ScrollToPositionArguments();
-    method public int getColumn();
-    method public int getRow();
-  }
-
-  public static final class AccessibilityViewCommand.SetProgressArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.SetProgressArguments();
-    method public float getProgress();
-  }
-
-  public static final class AccessibilityViewCommand.SetSelectionArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.SetSelectionArguments();
-    method public int getEnd();
-    method public int getStart();
-  }
-
-  public static final class AccessibilityViewCommand.SetTextArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.SetTextArguments();
-    method public CharSequence? getText();
-  }
-
-  public class AccessibilityWindowInfoCompat {
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getAnchor();
-    method public void getBoundsInScreen(android.graphics.Rect);
-    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getChild(int);
-    method public int getChildCount();
-    method public int getId();
-    method public int getLayer();
-    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getParent();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getRoot();
-    method public CharSequence? getTitle();
-    method public int getType();
-    method public boolean isAccessibilityFocused();
-    method public boolean isActive();
-    method public boolean isFocused();
-    method public static androidx.core.view.accessibility.AccessibilityWindowInfoCompat? obtain();
-    method public static androidx.core.view.accessibility.AccessibilityWindowInfoCompat? obtain(androidx.core.view.accessibility.AccessibilityWindowInfoCompat?);
-    method public void recycle();
-    field public static final int TYPE_ACCESSIBILITY_OVERLAY = 4; // 0x4
-    field public static final int TYPE_APPLICATION = 1; // 0x1
-    field public static final int TYPE_INPUT_METHOD = 2; // 0x2
-    field public static final int TYPE_SPLIT_SCREEN_DIVIDER = 5; // 0x5
-    field public static final int TYPE_SYSTEM = 3; // 0x3
-  }
-
-}
-
-package androidx.core.view.animation {
-
-  public final class PathInterpolatorCompat {
-    method public static android.view.animation.Interpolator create(android.graphics.Path);
-    method public static android.view.animation.Interpolator create(float, float);
-    method public static android.view.animation.Interpolator create(float, float, float, float);
-  }
-
-}
-
-package androidx.core.view.inputmethod {
-
-  public final class EditorInfoCompat {
-    ctor @Deprecated public EditorInfoCompat();
-    method public static String![] getContentMimeTypes(android.view.inputmethod.EditorInfo);
-    method public static CharSequence? getInitialSelectedText(android.view.inputmethod.EditorInfo, int);
-    method public static CharSequence? getInitialTextAfterCursor(android.view.inputmethod.EditorInfo, int, int);
-    method public static CharSequence? getInitialTextBeforeCursor(android.view.inputmethod.EditorInfo, int, int);
-    method public static void setContentMimeTypes(android.view.inputmethod.EditorInfo, String![]?);
-    method public static void setInitialSurroundingSubText(android.view.inputmethod.EditorInfo, CharSequence, int);
-    method public static void setInitialSurroundingText(android.view.inputmethod.EditorInfo, CharSequence);
-    field public static final int IME_FLAG_FORCE_ASCII = -2147483648; // 0x80000000
-    field public static final int IME_FLAG_NO_PERSONALIZED_LEARNING = 16777216; // 0x1000000
-  }
-
-  public final class InputConnectionCompat {
-    ctor @Deprecated public InputConnectionCompat();
-    method public static boolean commitContent(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle?);
-    method @Deprecated public static android.view.inputmethod.InputConnection createWrapper(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputConnectionCompat.OnCommitContentListener);
-    method public static android.view.inputmethod.InputConnection createWrapper(android.view.View, android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo);
-    field public static final int INPUT_CONTENT_GRANT_READ_URI_PERMISSION = 1; // 0x1
-  }
-
-  public static interface InputConnectionCompat.OnCommitContentListener {
-    method public boolean onCommitContent(androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle?);
-  }
-
-  public final class InputContentInfoCompat {
-    ctor public InputContentInfoCompat(android.net.Uri, android.content.ClipDescription, android.net.Uri?);
-    method public android.net.Uri getContentUri();
-    method public android.content.ClipDescription getDescription();
-    method public android.net.Uri? getLinkUri();
-    method public void releasePermission();
-    method public void requestPermission();
-    method public Object? unwrap();
-    method public static androidx.core.view.inputmethod.InputContentInfoCompat? wrap(Object?);
-  }
-
-}
-
-package androidx.core.widget {
-
-  public abstract class AutoScrollHelper implements android.view.View.OnTouchListener {
-    ctor public AutoScrollHelper(android.view.View);
-    method public abstract boolean canTargetScrollHorizontally(int);
-    method public abstract boolean canTargetScrollVertically(int);
-    method public boolean isEnabled();
-    method public boolean isExclusive();
-    method public boolean onTouch(android.view.View!, android.view.MotionEvent!);
-    method public abstract void scrollTargetBy(int, int);
-    method public androidx.core.widget.AutoScrollHelper setActivationDelay(int);
-    method public androidx.core.widget.AutoScrollHelper setEdgeType(int);
-    method public androidx.core.widget.AutoScrollHelper! setEnabled(boolean);
-    method public androidx.core.widget.AutoScrollHelper! setExclusive(boolean);
-    method public androidx.core.widget.AutoScrollHelper setMaximumEdges(float, float);
-    method public androidx.core.widget.AutoScrollHelper setMaximumVelocity(float, float);
-    method public androidx.core.widget.AutoScrollHelper setMinimumVelocity(float, float);
-    method public androidx.core.widget.AutoScrollHelper setRampDownDuration(int);
-    method public androidx.core.widget.AutoScrollHelper setRampUpDuration(int);
-    method public androidx.core.widget.AutoScrollHelper setRelativeEdges(float, float);
-    method public androidx.core.widget.AutoScrollHelper setRelativeVelocity(float, float);
-    field public static final int EDGE_TYPE_INSIDE = 0; // 0x0
-    field public static final int EDGE_TYPE_INSIDE_EXTEND = 1; // 0x1
-    field public static final int EDGE_TYPE_OUTSIDE = 2; // 0x2
-    field public static final float NO_MAX = 3.4028235E38f;
-    field public static final float NO_MIN = 0.0f;
-    field public static final float RELATIVE_UNSPECIFIED = 0.0f;
-  }
-
-  public final class CheckedTextViewCompat {
-    method public static android.graphics.drawable.Drawable? getCheckMarkDrawable(android.widget.CheckedTextView);
-    method public static android.content.res.ColorStateList? getCheckMarkTintList(android.widget.CheckedTextView);
-    method public static android.graphics.PorterDuff.Mode? getCheckMarkTintMode(android.widget.CheckedTextView);
-    method public static void setCheckMarkTintList(android.widget.CheckedTextView, android.content.res.ColorStateList?);
-    method public static void setCheckMarkTintMode(android.widget.CheckedTextView, android.graphics.PorterDuff.Mode?);
-  }
-
-  public final class CompoundButtonCompat {
-    method public static android.graphics.drawable.Drawable? getButtonDrawable(android.widget.CompoundButton);
-    method public static android.content.res.ColorStateList? getButtonTintList(android.widget.CompoundButton);
-    method public static android.graphics.PorterDuff.Mode? getButtonTintMode(android.widget.CompoundButton);
-    method public static void setButtonTintList(android.widget.CompoundButton, android.content.res.ColorStateList?);
-    method public static void setButtonTintMode(android.widget.CompoundButton, android.graphics.PorterDuff.Mode?);
-  }
-
-  public class ContentLoadingProgressBar extends android.widget.ProgressBar {
-    ctor public ContentLoadingProgressBar(android.content.Context);
-    ctor public ContentLoadingProgressBar(android.content.Context, android.util.AttributeSet?);
-    method public void hide();
-    method public void onAttachedToWindow();
-    method public void onDetachedFromWindow();
-    method public void show();
-  }
-
-  public final class EdgeEffectCompat {
-    ctor @Deprecated public EdgeEffectCompat(android.content.Context!);
-    method public static android.widget.EdgeEffect create(android.content.Context, android.util.AttributeSet?);
-    method @Deprecated public boolean draw(android.graphics.Canvas!);
-    method @Deprecated public void finish();
-    method public static float getDistance(android.widget.EdgeEffect);
-    method @Deprecated public boolean isFinished();
-    method @Deprecated public boolean onAbsorb(int);
-    method @Deprecated public boolean onPull(float);
-    method @Deprecated public boolean onPull(float, float);
-    method public static void onPull(android.widget.EdgeEffect, float, float);
-    method public static float onPullDistance(android.widget.EdgeEffect, float, float);
-    method @Deprecated public boolean onRelease();
-    method @Deprecated public void setSize(int, int);
-  }
-
-  public class ImageViewCompat {
-    method public static android.content.res.ColorStateList? getImageTintList(android.widget.ImageView);
-    method public static android.graphics.PorterDuff.Mode? getImageTintMode(android.widget.ImageView);
-    method public static void setImageTintList(android.widget.ImageView, android.content.res.ColorStateList?);
-    method public static void setImageTintMode(android.widget.ImageView, android.graphics.PorterDuff.Mode?);
-  }
-
-  public final class ListPopupWindowCompat {
-    method @Deprecated public static android.view.View.OnTouchListener! createDragToOpenListener(Object!, android.view.View!);
-    method public static android.view.View.OnTouchListener? createDragToOpenListener(android.widget.ListPopupWindow, android.view.View);
-  }
-
-  public class ListViewAutoScrollHelper extends androidx.core.widget.AutoScrollHelper {
-    ctor public ListViewAutoScrollHelper(android.widget.ListView);
-    method public boolean canTargetScrollHorizontally(int);
-    method public boolean canTargetScrollVertically(int);
-    method public void scrollTargetBy(int, int);
-  }
-
-  public final class ListViewCompat {
-    method public static boolean canScrollList(android.widget.ListView, int);
-    method public static void scrollListBy(android.widget.ListView, int);
-  }
-
-  public class NestedScrollView extends android.widget.FrameLayout implements androidx.core.view.NestedScrollingChild3 androidx.core.view.NestedScrollingParent3 androidx.core.view.ScrollingView {
-    ctor public NestedScrollView(android.content.Context);
-    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet?);
-    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet?, int);
-    method public boolean arrowScroll(int);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollExtent();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollOffset();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollRange();
-    method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollExtent();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollOffset();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollRange();
-    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
-    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]);
-    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
-    method public boolean executeKeyEvent(android.view.KeyEvent);
-    method public void fling(int);
-    method public boolean fullScroll(int);
-    method public int getMaxScrollAmount();
-    method public boolean hasNestedScrollingParent(int);
-    method public boolean isFillViewport();
-    method public boolean isSmoothScrollingEnabled();
-    method public void onAttachedToWindow();
-    method public void onNestedPreScroll(android.view.View, int, int, int[], int);
-    method public void onNestedScroll(android.view.View, int, int, int, int, int, int[]);
-    method public void onNestedScroll(android.view.View, int, int, int, int, int);
-    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
-    method public boolean onStartNestedScroll(android.view.View, android.view.View, int, int);
-    method public void onStopNestedScroll(android.view.View, int);
-    method public boolean pageScroll(int);
-    method public void setFillViewport(boolean);
-    method public void setOnScrollChangeListener(androidx.core.widget.NestedScrollView.OnScrollChangeListener?);
-    method public void setSmoothScrollingEnabled(boolean);
-    method public final void smoothScrollBy(int, int);
-    method public final void smoothScrollBy(int, int, int);
-    method public final void smoothScrollTo(int, int);
-    method public final void smoothScrollTo(int, int, int);
-    method public boolean startNestedScroll(int, int);
-    method public void stopNestedScroll(int);
-  }
-
-  public static interface NestedScrollView.OnScrollChangeListener {
-    method public void onScrollChange(androidx.core.widget.NestedScrollView, int, int, int, int);
-  }
-
-  public final class PopupMenuCompat {
-    method public static android.view.View.OnTouchListener? getDragToOpenListener(Object);
-  }
-
-  public final class PopupWindowCompat {
-    method public static boolean getOverlapAnchor(android.widget.PopupWindow);
-    method public static int getWindowLayoutType(android.widget.PopupWindow);
-    method public static void setOverlapAnchor(android.widget.PopupWindow, boolean);
-    method public static void setWindowLayoutType(android.widget.PopupWindow, int);
-    method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
-  }
-
-  @Deprecated public final class ScrollerCompat {
-    method @Deprecated public void abortAnimation();
-    method @Deprecated public boolean computeScrollOffset();
-    method @Deprecated public static androidx.core.widget.ScrollerCompat! create(android.content.Context!);
-    method @Deprecated public static androidx.core.widget.ScrollerCompat! create(android.content.Context!, android.view.animation.Interpolator!);
-    method @Deprecated public void fling(int, int, int, int, int, int, int, int);
-    method @Deprecated public void fling(int, int, int, int, int, int, int, int, int, int);
-    method @Deprecated public float getCurrVelocity();
-    method @Deprecated public int getCurrX();
-    method @Deprecated public int getCurrY();
-    method @Deprecated public int getFinalX();
-    method @Deprecated public int getFinalY();
-    method @Deprecated public boolean isFinished();
-    method @Deprecated public boolean isOverScrolled();
-    method @Deprecated public void notifyHorizontalEdgeReached(int, int, int);
-    method @Deprecated public void notifyVerticalEdgeReached(int, int, int);
-    method @Deprecated public boolean springBack(int, int, int, int, int, int);
-    method @Deprecated public void startScroll(int, int, int, int);
-    method @Deprecated public void startScroll(int, int, int, int, int);
-  }
-
-  public final class TextViewCompat {
-    method public static int getAutoSizeMaxTextSize(android.widget.TextView);
-    method public static int getAutoSizeMinTextSize(android.widget.TextView);
-    method public static int getAutoSizeStepGranularity(android.widget.TextView);
-    method public static int[] getAutoSizeTextAvailableSizes(android.widget.TextView);
-    method public static int getAutoSizeTextType(android.widget.TextView);
-    method public static android.content.res.ColorStateList? getCompoundDrawableTintList(android.widget.TextView);
-    method public static android.graphics.PorterDuff.Mode? getCompoundDrawableTintMode(android.widget.TextView);
-    method public static android.graphics.drawable.Drawable![] getCompoundDrawablesRelative(android.widget.TextView);
-    method public static int getFirstBaselineToTopHeight(android.widget.TextView);
-    method public static int getLastBaselineToBottomHeight(android.widget.TextView);
-    method public static int getMaxLines(android.widget.TextView);
-    method public static int getMinLines(android.widget.TextView);
-    method public static androidx.core.text.PrecomputedTextCompat.Params getTextMetricsParams(android.widget.TextView);
-    method public static void setAutoSizeTextTypeUniformWithConfiguration(android.widget.TextView, int, int, int, int) throws java.lang.IllegalArgumentException;
-    method public static void setAutoSizeTextTypeUniformWithPresetSizes(android.widget.TextView, int[], int) throws java.lang.IllegalArgumentException;
-    method public static void setAutoSizeTextTypeWithDefaults(android.widget.TextView, int);
-    method public static void setCompoundDrawableTintList(android.widget.TextView, android.content.res.ColorStateList?);
-    method public static void setCompoundDrawableTintMode(android.widget.TextView, android.graphics.PorterDuff.Mode?);
-    method public static void setCompoundDrawablesRelative(android.widget.TextView, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?);
-    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?);
-    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, @DrawableRes int, @DrawableRes int, @DrawableRes int, @DrawableRes int);
-    method public static void setCustomSelectionActionModeCallback(android.widget.TextView, android.view.ActionMode.Callback);
-    method public static void setFirstBaselineToTopHeight(android.widget.TextView, @IntRange(from=0) @Px int);
-    method public static void setLastBaselineToBottomHeight(android.widget.TextView, @IntRange(from=0) @Px int);
-    method public static void setLineHeight(android.widget.TextView, @IntRange(from=0) @Px int);
-    method public static void setPrecomputedText(android.widget.TextView, androidx.core.text.PrecomputedTextCompat);
-    method public static void setTextAppearance(android.widget.TextView, @StyleRes int);
-    method public static void setTextMetricsParams(android.widget.TextView, androidx.core.text.PrecomputedTextCompat.Params);
-    field public static final int AUTO_SIZE_TEXT_TYPE_NONE = 0; // 0x0
-    field public static final int AUTO_SIZE_TEXT_TYPE_UNIFORM = 1; // 0x1
-  }
-
-  public interface TintableCompoundButton {
-    method public android.content.res.ColorStateList? getSupportButtonTintList();
-    method public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
-    method public void setSupportButtonTintList(android.content.res.ColorStateList?);
-    method public void setSupportButtonTintMode(android.graphics.PorterDuff.Mode?);
-  }
-
-  public interface TintableCompoundDrawablesView {
-    method public android.content.res.ColorStateList? getSupportCompoundDrawablesTintList();
-    method public android.graphics.PorterDuff.Mode? getSupportCompoundDrawablesTintMode();
-    method public void setSupportCompoundDrawablesTintList(android.content.res.ColorStateList?);
-    method public void setSupportCompoundDrawablesTintMode(android.graphics.PorterDuff.Mode?);
-  }
-
-}
-
diff --git a/core/core/api/current.txt b/core/core/api/current.txt
index ac52137..83fef5e 100644
--- a/core/core/api/current.txt
+++ b/core/core/api/current.txt
@@ -1010,10 +1010,15 @@
     method public static <T> T? getSystemService(android.content.Context, Class<T!>);
     method public static String? getSystemServiceName(android.content.Context, Class<?>);
     method public static boolean isDeviceProtectedStorage(android.content.Context);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, int);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, String?, android.os.Handler?, int);
     method public static boolean startActivities(android.content.Context, android.content.Intent![]);
     method public static boolean startActivities(android.content.Context, android.content.Intent![], android.os.Bundle?);
     method public static void startActivity(android.content.Context, android.content.Intent, android.os.Bundle?);
     method public static void startForegroundService(android.content.Context, android.content.Intent);
+    field public static final int RECEIVER_EXPORTED = 2; // 0x2
+    field public static final int RECEIVER_NOT_EXPORTED = 4; // 0x4
+    field public static final int RECEIVER_VISIBLE_TO_INSTANT_APPS = 1; // 0x1
   }
 
   public class FileProvider extends android.content.ContentProvider {
@@ -1735,6 +1740,7 @@
     method public java.util.Locale? getFirstMatch(String![]);
     method @IntRange(from=0xffffffff) public int indexOf(java.util.Locale?);
     method public boolean isEmpty();
+    method @RequiresApi(21) public static boolean matchesLanguageAndScript(java.util.Locale, java.util.Locale);
     method @IntRange(from=0) public int size();
     method public String toLanguageTags();
     method public Object? unwrap();
@@ -1753,7 +1759,18 @@
   }
 
   public final class ParcelCompat {
+    method public static <T> T![]? readArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> java.util.ArrayList<T!>? readArrayList(android.os.Parcel, ClassLoader?, Class<? extends T>);
     method public static boolean readBoolean(android.os.Parcel);
+    method public static <K, V> java.util.HashMap<K!,V!>? readHashMap(android.os.Parcel, ClassLoader?, Class<? extends K>, Class<? extends V>);
+    method public static <T> void readList(android.os.Parcel, java.util.List<? super T>, ClassLoader?, Class<T!>);
+    method public static <K, V> void readMap(android.os.Parcel, java.util.Map<? super K,? super V>, ClassLoader?, Class<K!>, Class<V!>);
+    method public static <T extends android.os.Parcelable> T? readParcelable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> T![]? readParcelableArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(30) public static <T> android.os.Parcelable.Creator<T!>? readParcelableCreator(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.Q) public static <T> java.util.List<T!> readParcelableList(android.os.Parcel, java.util.List<T!>, ClassLoader?, Class<T!>);
+    method public static <T extends java.io.Serializable> T? readSerializable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> android.util.SparseArray<T!>? readSparseArray(android.os.Parcel, ClassLoader?, Class<? extends T>);
     method public static void writeBoolean(android.os.Parcel, boolean);
   }
 
@@ -3022,6 +3039,9 @@
     method public static void setContentChangeTypes(android.view.accessibility.AccessibilityEvent, int);
     method public static void setMovementGranularity(android.view.accessibility.AccessibilityEvent, int);
     field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_CANCELLED = 512; // 0x200
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_DROPPED = 256; // 0x100
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_STARTED = 128; // 0x80
     field public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 16; // 0x10
     field public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 32; // 0x20
     field public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 8; // 0x8
@@ -3118,6 +3138,7 @@
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat? getTouchDelegateInfo();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalAfter();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalBefore();
+    method public String? getUniqueId();
     method public String! getViewIdResourceName();
     method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat! getWindow();
     method public int getWindowId();
@@ -3211,6 +3232,7 @@
     method public void setTraversalAfter(android.view.View!, int);
     method public void setTraversalBefore(android.view.View!);
     method public void setTraversalBefore(android.view.View!, int);
+    method public void setUniqueId(String?);
     method public void setViewIdResourceName(String!);
     method public void setVisibleToUser(boolean);
     method public android.view.accessibility.AccessibilityNodeInfo! unwrap();
@@ -3272,6 +3294,9 @@
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COPY;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CUT;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_DISMISS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_CANCEL;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_DROP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_START;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_EXPAND;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_FOCUS;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_HIDE_TOOLTIP;
diff --git a/core/core/api/public_plus_experimental_1.8.0-beta02.txt b/core/core/api/public_plus_experimental_1.8.0-beta02.txt
index 8ea9b73..abd1c17 100644
--- a/core/core/api/public_plus_experimental_1.8.0-beta02.txt
+++ b/core/core/api/public_plus_experimental_1.8.0-beta02.txt
@@ -1690,8 +1690,8 @@
     method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.Q) public static boolean isAtLeastQ();
     method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.R) public static boolean isAtLeastR();
     method @Deprecated @ChecksSdkIntAtLeast(api=31, codename="S") public static boolean isAtLeastS();
-    method @Deprecated @ChecksSdkIntAtLeast(api=32, codename="Sv2") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastSv2();
-    method @Deprecated @ChecksSdkIntAtLeast(codename="Tiramisu") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastT();
+    method @ChecksSdkIntAtLeast(api=32, codename="Sv2") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastSv2();
+    method @ChecksSdkIntAtLeast(codename="Tiramisu") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastT();
   }
 
   @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface BuildCompat.PrereleaseSdkCheck {
diff --git a/core/core/api/public_plus_experimental_current.txt b/core/core/api/public_plus_experimental_current.txt
index 8ad2d8f..d079c8d 100644
--- a/core/core/api/public_plus_experimental_current.txt
+++ b/core/core/api/public_plus_experimental_current.txt
@@ -1010,10 +1010,15 @@
     method public static <T> T? getSystemService(android.content.Context, Class<T!>);
     method public static String? getSystemServiceName(android.content.Context, Class<?>);
     method public static boolean isDeviceProtectedStorage(android.content.Context);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, int);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, String?, android.os.Handler?, int);
     method public static boolean startActivities(android.content.Context, android.content.Intent![]);
     method public static boolean startActivities(android.content.Context, android.content.Intent![], android.os.Bundle?);
     method public static void startActivity(android.content.Context, android.content.Intent, android.os.Bundle?);
     method public static void startForegroundService(android.content.Context, android.content.Intent);
+    field public static final int RECEIVER_EXPORTED = 2; // 0x2
+    field public static final int RECEIVER_NOT_EXPORTED = 4; // 0x4
+    field public static final int RECEIVER_VISIBLE_TO_INSTANT_APPS = 1; // 0x1
   }
 
   public class FileProvider extends android.content.ContentProvider {
@@ -1741,6 +1746,7 @@
     method public java.util.Locale? getFirstMatch(String![]);
     method @IntRange(from=0xffffffff) public int indexOf(java.util.Locale?);
     method public boolean isEmpty();
+    method @RequiresApi(21) public static boolean matchesLanguageAndScript(java.util.Locale, java.util.Locale);
     method @IntRange(from=0) public int size();
     method public String toLanguageTags();
     method public Object? unwrap();
@@ -1759,7 +1765,18 @@
   }
 
   public final class ParcelCompat {
+    method public static <T> T![]? readArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> java.util.ArrayList<T!>? readArrayList(android.os.Parcel, ClassLoader?, Class<? extends T>);
     method public static boolean readBoolean(android.os.Parcel);
+    method public static <K, V> java.util.HashMap<K!,V!>? readHashMap(android.os.Parcel, ClassLoader?, Class<? extends K>, Class<? extends V>);
+    method public static <T> void readList(android.os.Parcel, java.util.List<? super T>, ClassLoader?, Class<T!>);
+    method public static <K, V> void readMap(android.os.Parcel, java.util.Map<? super K,? super V>, ClassLoader?, Class<K!>, Class<V!>);
+    method public static <T extends android.os.Parcelable> T? readParcelable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> T![]? readParcelableArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(30) public static <T> android.os.Parcelable.Creator<T!>? readParcelableCreator(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.Q) public static <T> java.util.List<T!> readParcelableList(android.os.Parcel, java.util.List<T!>, ClassLoader?, Class<T!>);
+    method public static <T extends java.io.Serializable> T? readSerializable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> android.util.SparseArray<T!>? readSparseArray(android.os.Parcel, ClassLoader?, Class<? extends T>);
     method public static void writeBoolean(android.os.Parcel, boolean);
   }
 
@@ -3028,6 +3045,9 @@
     method public static void setContentChangeTypes(android.view.accessibility.AccessibilityEvent, int);
     method public static void setMovementGranularity(android.view.accessibility.AccessibilityEvent, int);
     field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_CANCELLED = 512; // 0x200
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_DROPPED = 256; // 0x100
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_STARTED = 128; // 0x80
     field public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 16; // 0x10
     field public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 32; // 0x20
     field public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 8; // 0x8
@@ -3124,6 +3144,7 @@
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat? getTouchDelegateInfo();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalAfter();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalBefore();
+    method public String? getUniqueId();
     method public String! getViewIdResourceName();
     method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat! getWindow();
     method public int getWindowId();
@@ -3217,6 +3238,7 @@
     method public void setTraversalAfter(android.view.View!, int);
     method public void setTraversalBefore(android.view.View!);
     method public void setTraversalBefore(android.view.View!, int);
+    method public void setUniqueId(String?);
     method public void setViewIdResourceName(String!);
     method public void setVisibleToUser(boolean);
     method public android.view.accessibility.AccessibilityNodeInfo! unwrap();
@@ -3278,6 +3300,9 @@
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COPY;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CUT;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_DISMISS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_CANCEL;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_DROP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_START;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_EXPAND;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_FOCUS;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_HIDE_TOOLTIP;
diff --git a/core/core/api/res-1.8.0-beta01.txt b/core/core/api/res-1.8.0-beta01.txt
deleted file mode 100644
index dd913d3..0000000
--- a/core/core/api/res-1.8.0-beta01.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-attr alpha
-attr font
-attr fontProviderAuthority
-attr fontProviderCerts
-attr fontProviderFetchStrategy
-attr fontProviderFetchTimeout
-attr fontProviderPackage
-attr fontProviderQuery
-attr fontProviderSystemFontFamily
-attr fontStyle
-attr fontVariationSettings
-attr fontWeight
-attr lStar
-attr queryPatterns
-attr shortcutMatchRequired
-attr ttcIndex
-style TextAppearance_Compat_Notification
-style TextAppearance_Compat_Notification_Info
-style TextAppearance_Compat_Notification_Line2
-style TextAppearance_Compat_Notification_Time
-style TextAppearance_Compat_Notification_Title
diff --git a/core/core/api/restricted_1.8.0-beta01.txt b/core/core/api/restricted_1.8.0-beta01.txt
deleted file mode 100644
index ec250b5..0000000
--- a/core/core/api/restricted_1.8.0-beta01.txt
+++ /dev/null
@@ -1,4263 +0,0 @@
-// Signature format: 4.0
-package android.support.v4.os {
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ResultReceiver implements android.os.Parcelable {
-    ctor public ResultReceiver(android.os.Handler!);
-    method public int describeContents();
-    method protected void onReceiveResult(int, android.os.Bundle!);
-    method public void send(int, android.os.Bundle!);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.support.v4.os.ResultReceiver!>! CREATOR;
-  }
-
-}
-
-package androidx.core.accessibilityservice {
-
-  public final class AccessibilityServiceInfoCompat {
-    method public static String capabilityToString(int);
-    method public static String feedbackTypeToString(int);
-    method public static String? flagToString(int);
-    method public static int getCapabilities(android.accessibilityservice.AccessibilityServiceInfo);
-    method public static String? loadDescription(android.accessibilityservice.AccessibilityServiceInfo, android.content.pm.PackageManager);
-    field public static final int CAPABILITY_CAN_FILTER_KEY_EVENTS = 8; // 0x8
-    field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
-    field public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2; // 0x2
-    field public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1; // 0x1
-    field public static final int FEEDBACK_ALL_MASK = -1; // 0xffffffff
-    field public static final int FEEDBACK_BRAILLE = 32; // 0x20
-    field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
-    field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
-    field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
-    field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
-    field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
-  }
-
-}
-
-package androidx.core.app {
-
-  public class ActivityCompat extends androidx.core.content.ContextCompat {
-    ctor protected ActivityCompat();
-    method public static void finishAffinity(android.app.Activity);
-    method public static void finishAfterTransition(android.app.Activity);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.app.ActivityCompat.PermissionCompatDelegate? getPermissionCompatDelegate();
-    method public static android.net.Uri? getReferrer(android.app.Activity);
-    method @Deprecated public static boolean invalidateOptionsMenu(android.app.Activity!);
-    method public static boolean isLaunchedFromBubble(android.app.Activity);
-    method public static void postponeEnterTransition(android.app.Activity);
-    method public static void recreate(android.app.Activity);
-    method public static androidx.core.view.DragAndDropPermissionsCompat? requestDragAndDropPermissions(android.app.Activity, android.view.DragEvent);
-    method public static void requestPermissions(android.app.Activity, String![], @IntRange(from=0) int);
-    method public static <T extends android.view.View> T requireViewById(android.app.Activity, @IdRes int);
-    method public static void setEnterSharedElementCallback(android.app.Activity, androidx.core.app.SharedElementCallback?);
-    method public static void setExitSharedElementCallback(android.app.Activity, androidx.core.app.SharedElementCallback?);
-    method public static void setLocusContext(android.app.Activity, androidx.core.content.LocusIdCompat?, android.os.Bundle?);
-    method public static void setPermissionCompatDelegate(androidx.core.app.ActivityCompat.PermissionCompatDelegate?);
-    method public static boolean shouldShowRequestPermissionRationale(android.app.Activity, String);
-    method public static void startActivityForResult(android.app.Activity, android.content.Intent, int, android.os.Bundle?);
-    method public static void startIntentSenderForResult(android.app.Activity, android.content.IntentSender, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
-    method public static void startPostponedEnterTransition(android.app.Activity);
-  }
-
-  public static interface ActivityCompat.OnRequestPermissionsResultCallback {
-    method public void onRequestPermissionsResult(int, String![], int[]);
-  }
-
-  public static interface ActivityCompat.PermissionCompatDelegate {
-    method public boolean onActivityResult(android.app.Activity, @IntRange(from=0) int, int, android.content.Intent?);
-    method public boolean requestPermissions(android.app.Activity, String![], @IntRange(from=0) int);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static interface ActivityCompat.RequestPermissionsRequestCodeValidator {
-    method public void validateRequestPermissionsRequestCode(int);
-  }
-
-  public final class ActivityManagerCompat {
-    method public static boolean isLowRamDevice(android.app.ActivityManager);
-  }
-
-  public class ActivityOptionsCompat {
-    ctor protected ActivityOptionsCompat();
-    method public android.graphics.Rect? getLaunchBounds();
-    method public static androidx.core.app.ActivityOptionsCompat makeBasic();
-    method public static androidx.core.app.ActivityOptionsCompat makeClipRevealAnimation(android.view.View, int, int, int, int);
-    method public static androidx.core.app.ActivityOptionsCompat makeCustomAnimation(android.content.Context, int, int);
-    method public static androidx.core.app.ActivityOptionsCompat makeScaleUpAnimation(android.view.View, int, int, int, int);
-    method public static androidx.core.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, android.view.View, String);
-    method public static androidx.core.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, androidx.core.util.Pair<android.view.View!,java.lang.String!>!...);
-    method public static androidx.core.app.ActivityOptionsCompat makeTaskLaunchBehind();
-    method public static androidx.core.app.ActivityOptionsCompat makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
-    method public void requestUsageTimeReport(android.app.PendingIntent);
-    method public androidx.core.app.ActivityOptionsCompat setLaunchBounds(android.graphics.Rect?);
-    method public android.os.Bundle? toBundle();
-    method public void update(androidx.core.app.ActivityOptionsCompat);
-    field public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
-    field public static final String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
-  }
-
-  public final class AlarmManagerCompat {
-    method public static void setAlarmClock(android.app.AlarmManager, long, android.app.PendingIntent, android.app.PendingIntent);
-    method public static void setAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
-    method public static void setExact(android.app.AlarmManager, int, long, android.app.PendingIntent);
-    method public static void setExactAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
-  }
-
-  @RequiresApi(28) public class AppComponentFactory extends android.app.AppComponentFactory {
-    ctor public AppComponentFactory();
-    method public final android.app.Activity instantiateActivity(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public android.app.Activity instantiateActivityCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public final android.app.Application instantiateApplication(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public android.app.Application instantiateApplicationCompat(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public final android.content.ContentProvider instantiateProvider(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public android.content.ContentProvider instantiateProviderCompat(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public final android.content.BroadcastReceiver instantiateReceiver(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public android.content.BroadcastReceiver instantiateReceiverCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public final android.app.Service instantiateService(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-    method public android.app.Service instantiateServiceCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
-  }
-
-  public class AppLaunchChecker {
-    ctor @Deprecated public AppLaunchChecker();
-    method public static boolean hasStartedFromLauncher(android.content.Context);
-    method public static void onActivityCreate(android.app.Activity);
-  }
-
-  public final class AppOpsManagerCompat {
-    method public static int checkOrNoteProxyOp(android.content.Context, int, String, String);
-    method public static int noteOp(android.content.Context, String, int, String);
-    method public static int noteOpNoThrow(android.content.Context, String, int, String);
-    method public static int noteProxyOp(android.content.Context, String, String);
-    method public static int noteProxyOpNoThrow(android.content.Context, String, String);
-    method public static String? permissionToOp(String);
-    field public static final int MODE_ALLOWED = 0; // 0x0
-    field public static final int MODE_DEFAULT = 3; // 0x3
-    field public static final int MODE_ERRORED = 2; // 0x2
-    field public static final int MODE_IGNORED = 1; // 0x1
-  }
-
-  public final class BundleCompat {
-    method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
-    method public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ComponentActivity extends android.app.Activity implements androidx.core.view.KeyEventDispatcher.Component androidx.lifecycle.LifecycleOwner {
-    ctor public ComponentActivity();
-    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public <T extends androidx.core.app.ComponentActivity.ExtraData> T! getExtraData(Class<T!>!);
-    method public androidx.lifecycle.Lifecycle getLifecycle();
-    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void putExtraData(androidx.core.app.ComponentActivity.ExtraData!);
-    method protected final boolean shouldDumpInternalState(String![]?);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean superDispatchKeyEvent(android.view.KeyEvent);
-  }
-
-  @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static class ComponentActivity.ExtraData {
-    ctor @Deprecated public ComponentActivity.ExtraData();
-  }
-
-  @RequiresApi(api=28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class CoreComponentFactory extends android.app.AppComponentFactory {
-    ctor public CoreComponentFactory();
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static interface CoreComponentFactory.CompatWrapped {
-    method public Object! getWrapper();
-  }
-
-  public class DialogCompat {
-    method public static android.view.View requireViewById(android.app.Dialog, int);
-  }
-
-  public class FrameMetricsAggregator {
-    ctor public FrameMetricsAggregator();
-    ctor public FrameMetricsAggregator(@androidx.core.app.FrameMetricsAggregator.MetricType int);
-    method public void add(android.app.Activity);
-    method public android.util.SparseIntArray![]? getMetrics();
-    method public android.util.SparseIntArray![]? remove(android.app.Activity);
-    method public android.util.SparseIntArray![]? reset();
-    method public android.util.SparseIntArray![]? stop();
-    field public static final int ANIMATION_DURATION = 256; // 0x100
-    field public static final int ANIMATION_INDEX = 8; // 0x8
-    field public static final int COMMAND_DURATION = 32; // 0x20
-    field public static final int COMMAND_INDEX = 5; // 0x5
-    field public static final int DELAY_DURATION = 128; // 0x80
-    field public static final int DELAY_INDEX = 7; // 0x7
-    field public static final int DRAW_DURATION = 8; // 0x8
-    field public static final int DRAW_INDEX = 3; // 0x3
-    field public static final int EVERY_DURATION = 511; // 0x1ff
-    field public static final int INPUT_DURATION = 2; // 0x2
-    field public static final int INPUT_INDEX = 1; // 0x1
-    field public static final int LAYOUT_MEASURE_DURATION = 4; // 0x4
-    field public static final int LAYOUT_MEASURE_INDEX = 2; // 0x2
-    field public static final int SWAP_DURATION = 64; // 0x40
-    field public static final int SWAP_INDEX = 6; // 0x6
-    field public static final int SYNC_DURATION = 16; // 0x10
-    field public static final int SYNC_INDEX = 4; // 0x4
-    field public static final int TOTAL_DURATION = 1; // 0x1
-    field public static final int TOTAL_INDEX = 0; // 0x0
-  }
-
-  @IntDef(flag=true, value={androidx.core.app.FrameMetricsAggregator.TOTAL_DURATION, androidx.core.app.FrameMetricsAggregator.INPUT_DURATION, androidx.core.app.FrameMetricsAggregator.LAYOUT_MEASURE_DURATION, androidx.core.app.FrameMetricsAggregator.DRAW_DURATION, androidx.core.app.FrameMetricsAggregator.SYNC_DURATION, androidx.core.app.FrameMetricsAggregator.COMMAND_DURATION, androidx.core.app.FrameMetricsAggregator.SWAP_DURATION, androidx.core.app.FrameMetricsAggregator.DELAY_DURATION, androidx.core.app.FrameMetricsAggregator.ANIMATION_DURATION, androidx.core.app.FrameMetricsAggregator.EVERY_DURATION}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface FrameMetricsAggregator.MetricType {
-  }
-
-  @Deprecated public abstract class JobIntentService extends android.app.Service {
-    ctor @Deprecated public JobIntentService();
-    method @Deprecated public static void enqueueWork(android.content.Context, Class<?>, int, android.content.Intent);
-    method @Deprecated public static void enqueueWork(android.content.Context, android.content.ComponentName, int, android.content.Intent);
-    method @Deprecated public boolean isStopped();
-    method @Deprecated public android.os.IBinder! onBind(android.content.Intent);
-    method @Deprecated protected abstract void onHandleWork(android.content.Intent);
-    method @Deprecated public boolean onStopCurrentWork();
-    method @Deprecated public void setInterruptIfStopped(boolean);
-  }
-
-  public final class MultiWindowModeChangedInfo {
-    ctor public MultiWindowModeChangedInfo(boolean);
-    ctor @RequiresApi(26) public MultiWindowModeChangedInfo(boolean, android.content.res.Configuration);
-    method @RequiresApi(26) public android.content.res.Configuration getNewConfig();
-    method public boolean isInMultiWindowMode();
-  }
-
-  public final class NavUtils {
-    method public static android.content.Intent? getParentActivityIntent(android.app.Activity);
-    method public static android.content.Intent? getParentActivityIntent(android.content.Context, Class<?>) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public static android.content.Intent? getParentActivityIntent(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public static String? getParentActivityName(android.app.Activity);
-    method public static String? getParentActivityName(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public static void navigateUpFromSameTask(android.app.Activity);
-    method public static void navigateUpTo(android.app.Activity, android.content.Intent);
-    method public static boolean shouldUpRecreateTask(android.app.Activity, android.content.Intent);
-    field public static final String PARENT_ACTIVITY = "android.support.PARENT_ACTIVITY";
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface NotificationBuilderWithBuilderAccessor {
-    method public android.app.Notification.Builder! getBuilder();
-  }
-
-  public class NotificationChannelCompat {
-    method public boolean canBubble();
-    method public boolean canBypassDnd();
-    method public boolean canShowBadge();
-    method public android.media.AudioAttributes? getAudioAttributes();
-    method public String? getConversationId();
-    method public String? getDescription();
-    method public String? getGroup();
-    method public String getId();
-    method public int getImportance();
-    method public int getLightColor();
-    method @androidx.core.app.NotificationCompat.NotificationVisibility public int getLockscreenVisibility();
-    method public CharSequence? getName();
-    method public String? getParentChannelId();
-    method public android.net.Uri? getSound();
-    method public long[]? getVibrationPattern();
-    method public boolean isImportantConversation();
-    method public boolean shouldShowLights();
-    method public boolean shouldVibrate();
-    method public androidx.core.app.NotificationChannelCompat.Builder toBuilder();
-    field public static final String DEFAULT_CHANNEL_ID = "miscellaneous";
-  }
-
-  public static class NotificationChannelCompat.Builder {
-    ctor public NotificationChannelCompat.Builder(String, int);
-    method public androidx.core.app.NotificationChannelCompat build();
-    method public androidx.core.app.NotificationChannelCompat.Builder setConversationId(String, String);
-    method public androidx.core.app.NotificationChannelCompat.Builder setDescription(String?);
-    method public androidx.core.app.NotificationChannelCompat.Builder setGroup(String?);
-    method public androidx.core.app.NotificationChannelCompat.Builder setImportance(int);
-    method public androidx.core.app.NotificationChannelCompat.Builder setLightColor(int);
-    method public androidx.core.app.NotificationChannelCompat.Builder setLightsEnabled(boolean);
-    method public androidx.core.app.NotificationChannelCompat.Builder setName(CharSequence?);
-    method public androidx.core.app.NotificationChannelCompat.Builder setShowBadge(boolean);
-    method public androidx.core.app.NotificationChannelCompat.Builder setSound(android.net.Uri?, android.media.AudioAttributes?);
-    method public androidx.core.app.NotificationChannelCompat.Builder setVibrationEnabled(boolean);
-    method public androidx.core.app.NotificationChannelCompat.Builder setVibrationPattern(long[]?);
-  }
-
-  public class NotificationChannelGroupCompat {
-    method public java.util.List<androidx.core.app.NotificationChannelCompat!> getChannels();
-    method public String? getDescription();
-    method public String getId();
-    method public CharSequence? getName();
-    method public boolean isBlocked();
-    method public androidx.core.app.NotificationChannelGroupCompat.Builder toBuilder();
-  }
-
-  public static class NotificationChannelGroupCompat.Builder {
-    ctor public NotificationChannelGroupCompat.Builder(String);
-    method public androidx.core.app.NotificationChannelGroupCompat build();
-    method public androidx.core.app.NotificationChannelGroupCompat.Builder setDescription(String?);
-    method public androidx.core.app.NotificationChannelGroupCompat.Builder setName(CharSequence?);
-  }
-
-  public class NotificationCompat {
-    ctor @Deprecated public NotificationCompat();
-    method public static androidx.core.app.NotificationCompat.Action? getAction(android.app.Notification, int);
-    method public static int getActionCount(android.app.Notification);
-    method public static boolean getAllowSystemGeneratedContextualActions(android.app.Notification);
-    method public static boolean getAutoCancel(android.app.Notification);
-    method public static int getBadgeIconType(android.app.Notification);
-    method public static androidx.core.app.NotificationCompat.BubbleMetadata? getBubbleMetadata(android.app.Notification);
-    method public static String? getCategory(android.app.Notification);
-    method public static String? getChannelId(android.app.Notification);
-    method public static int getColor(android.app.Notification);
-    method @RequiresApi(19) public static CharSequence? getContentInfo(android.app.Notification);
-    method @RequiresApi(19) public static CharSequence? getContentText(android.app.Notification);
-    method @RequiresApi(19) public static CharSequence? getContentTitle(android.app.Notification);
-    method public static android.os.Bundle? getExtras(android.app.Notification);
-    method public static String? getGroup(android.app.Notification);
-    method @androidx.core.app.NotificationCompat.GroupAlertBehavior public static int getGroupAlertBehavior(android.app.Notification);
-    method @RequiresApi(21) public static java.util.List<androidx.core.app.NotificationCompat.Action!> getInvisibleActions(android.app.Notification);
-    method public static boolean getLocalOnly(android.app.Notification);
-    method public static androidx.core.content.LocusIdCompat? getLocusId(android.app.Notification);
-    method public static boolean getOngoing(android.app.Notification);
-    method public static boolean getOnlyAlertOnce(android.app.Notification);
-    method public static java.util.List<androidx.core.app.Person!> getPeople(android.app.Notification);
-    method public static android.app.Notification? getPublicVersion(android.app.Notification);
-    method public static CharSequence? getSettingsText(android.app.Notification);
-    method public static String? getShortcutId(android.app.Notification);
-    method @RequiresApi(19) public static boolean getShowWhen(android.app.Notification);
-    method public static String? getSortKey(android.app.Notification);
-    method @RequiresApi(19) public static CharSequence? getSubText(android.app.Notification);
-    method public static long getTimeoutAfter(android.app.Notification);
-    method @RequiresApi(19) public static boolean getUsesChronometer(android.app.Notification);
-    method @androidx.core.app.NotificationCompat.NotificationVisibility public static int getVisibility(android.app.Notification);
-    method public static boolean isGroupSummary(android.app.Notification);
-    field public static final int BADGE_ICON_LARGE = 2; // 0x2
-    field public static final int BADGE_ICON_NONE = 0; // 0x0
-    field public static final int BADGE_ICON_SMALL = 1; // 0x1
-    field public static final String CATEGORY_ALARM = "alarm";
-    field public static final String CATEGORY_CALL = "call";
-    field public static final String CATEGORY_EMAIL = "email";
-    field public static final String CATEGORY_ERROR = "err";
-    field public static final String CATEGORY_EVENT = "event";
-    field public static final String CATEGORY_LOCATION_SHARING = "location_sharing";
-    field public static final String CATEGORY_MESSAGE = "msg";
-    field public static final String CATEGORY_MISSED_CALL = "missed_call";
-    field public static final String CATEGORY_NAVIGATION = "navigation";
-    field public static final String CATEGORY_PROGRESS = "progress";
-    field public static final String CATEGORY_PROMO = "promo";
-    field public static final String CATEGORY_RECOMMENDATION = "recommendation";
-    field public static final String CATEGORY_REMINDER = "reminder";
-    field public static final String CATEGORY_SERVICE = "service";
-    field public static final String CATEGORY_SOCIAL = "social";
-    field public static final String CATEGORY_STATUS = "status";
-    field public static final String CATEGORY_STOPWATCH = "stopwatch";
-    field public static final String CATEGORY_SYSTEM = "sys";
-    field public static final String CATEGORY_TRANSPORT = "transport";
-    field public static final String CATEGORY_WORKOUT = "workout";
-    field @ColorInt public static final int COLOR_DEFAULT = 0; // 0x0
-    field public static final int DEFAULT_ALL = -1; // 0xffffffff
-    field public static final int DEFAULT_LIGHTS = 4; // 0x4
-    field public static final int DEFAULT_SOUND = 1; // 0x1
-    field public static final int DEFAULT_VIBRATE = 2; // 0x2
-    field public static final String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents";
-    field public static final String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
-    field public static final String EXTRA_BIG_TEXT = "android.bigText";
-    field public static final String EXTRA_CHANNEL_GROUP_ID = "android.intent.extra.CHANNEL_GROUP_ID";
-    field public static final String EXTRA_CHANNEL_ID = "android.intent.extra.CHANNEL_ID";
-    field public static final String EXTRA_CHRONOMETER_COUNT_DOWN = "android.chronometerCountDown";
-    field public static final String EXTRA_COLORIZED = "android.colorized";
-    field public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions";
-    field public static final String EXTRA_COMPAT_TEMPLATE = "androidx.core.app.extra.COMPAT_TEMPLATE";
-    field public static final String EXTRA_CONVERSATION_TITLE = "android.conversationTitle";
-    field public static final String EXTRA_HIDDEN_CONVERSATION_TITLE = "android.hiddenConversationTitle";
-    field public static final String EXTRA_HISTORIC_MESSAGES = "android.messages.historic";
-    field public static final String EXTRA_INFO_TEXT = "android.infoText";
-    field public static final String EXTRA_IS_GROUP_CONVERSATION = "android.isGroupConversation";
-    field public static final String EXTRA_LARGE_ICON = "android.largeIcon";
-    field public static final String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
-    field public static final String EXTRA_MEDIA_SESSION = "android.mediaSession";
-    field public static final String EXTRA_MESSAGES = "android.messages";
-    field public static final String EXTRA_MESSAGING_STYLE_USER = "android.messagingStyleUser";
-    field public static final String EXTRA_NOTIFICATION_ID = "android.intent.extra.NOTIFICATION_ID";
-    field public static final String EXTRA_NOTIFICATION_TAG = "android.intent.extra.NOTIFICATION_TAG";
-    field @Deprecated public static final String EXTRA_PEOPLE = "android.people";
-    field public static final String EXTRA_PEOPLE_LIST = "android.people.list";
-    field public static final String EXTRA_PICTURE = "android.picture";
-    field public static final String EXTRA_PICTURE_CONTENT_DESCRIPTION = "android.pictureContentDescription";
-    field public static final String EXTRA_PROGRESS = "android.progress";
-    field public static final String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
-    field public static final String EXTRA_PROGRESS_MAX = "android.progressMax";
-    field public static final String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
-    field public static final String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
-    field public static final String EXTRA_SHOW_BIG_PICTURE_WHEN_COLLAPSED = "android.showBigPictureWhenCollapsed";
-    field public static final String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
-    field public static final String EXTRA_SHOW_WHEN = "android.showWhen";
-    field public static final String EXTRA_SMALL_ICON = "android.icon";
-    field public static final String EXTRA_SUB_TEXT = "android.subText";
-    field public static final String EXTRA_SUMMARY_TEXT = "android.summaryText";
-    field public static final String EXTRA_TEMPLATE = "android.template";
-    field public static final String EXTRA_TEXT = "android.text";
-    field public static final String EXTRA_TEXT_LINES = "android.textLines";
-    field public static final String EXTRA_TITLE = "android.title";
-    field public static final String EXTRA_TITLE_BIG = "android.title.big";
-    field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
-    field public static final int FLAG_BUBBLE = 4096; // 0x1000
-    field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
-    field public static final int FLAG_GROUP_SUMMARY = 512; // 0x200
-    field @Deprecated public static final int FLAG_HIGH_PRIORITY = 128; // 0x80
-    field public static final int FLAG_INSISTENT = 4; // 0x4
-    field public static final int FLAG_LOCAL_ONLY = 256; // 0x100
-    field public static final int FLAG_NO_CLEAR = 32; // 0x20
-    field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
-    field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
-    field public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
-    field public static final int FOREGROUND_SERVICE_DEFAULT = 0; // 0x0
-    field public static final int FOREGROUND_SERVICE_DEFERRED = 2; // 0x2
-    field public static final int FOREGROUND_SERVICE_IMMEDIATE = 1; // 0x1
-    field public static final int GROUP_ALERT_ALL = 0; // 0x0
-    field public static final int GROUP_ALERT_CHILDREN = 2; // 0x2
-    field public static final int GROUP_ALERT_SUMMARY = 1; // 0x1
-    field public static final String GROUP_KEY_SILENT = "silent";
-    field public static final String INTENT_CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
-    field public static final int PRIORITY_DEFAULT = 0; // 0x0
-    field public static final int PRIORITY_HIGH = 1; // 0x1
-    field public static final int PRIORITY_LOW = -1; // 0xffffffff
-    field public static final int PRIORITY_MAX = 2; // 0x2
-    field public static final int PRIORITY_MIN = -2; // 0xfffffffe
-    field public static final int STREAM_DEFAULT = -1; // 0xffffffff
-    field public static final int VISIBILITY_PRIVATE = 0; // 0x0
-    field public static final int VISIBILITY_PUBLIC = 1; // 0x1
-    field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
-  }
-
-  public static class NotificationCompat.Action {
-    ctor public NotificationCompat.Action(int, CharSequence?, android.app.PendingIntent?);
-    ctor public NotificationCompat.Action(androidx.core.graphics.drawable.IconCompat?, CharSequence?, android.app.PendingIntent?);
-    method public android.app.PendingIntent? getActionIntent();
-    method public boolean getAllowGeneratedReplies();
-    method public androidx.core.app.RemoteInput![]? getDataOnlyRemoteInputs();
-    method public android.os.Bundle getExtras();
-    method @Deprecated public int getIcon();
-    method public androidx.core.graphics.drawable.IconCompat? getIconCompat();
-    method public androidx.core.app.RemoteInput![]? getRemoteInputs();
-    method @androidx.core.app.NotificationCompat.Action.SemanticAction public int getSemanticAction();
-    method public boolean getShowsUserInterface();
-    method public CharSequence? getTitle();
-    method public boolean isAuthenticationRequired();
-    method public boolean isContextual();
-    field public static final int SEMANTIC_ACTION_ARCHIVE = 5; // 0x5
-    field public static final int SEMANTIC_ACTION_CALL = 10; // 0xa
-    field public static final int SEMANTIC_ACTION_DELETE = 4; // 0x4
-    field public static final int SEMANTIC_ACTION_MARK_AS_READ = 2; // 0x2
-    field public static final int SEMANTIC_ACTION_MARK_AS_UNREAD = 3; // 0x3
-    field public static final int SEMANTIC_ACTION_MUTE = 6; // 0x6
-    field public static final int SEMANTIC_ACTION_NONE = 0; // 0x0
-    field public static final int SEMANTIC_ACTION_REPLY = 1; // 0x1
-    field public static final int SEMANTIC_ACTION_THUMBS_DOWN = 9; // 0x9
-    field public static final int SEMANTIC_ACTION_THUMBS_UP = 8; // 0x8
-    field public static final int SEMANTIC_ACTION_UNMUTE = 7; // 0x7
-    field public android.app.PendingIntent! actionIntent;
-    field @Deprecated public int icon;
-    field public CharSequence! title;
-  }
-
-  public static final class NotificationCompat.Action.Builder {
-    ctor public NotificationCompat.Action.Builder(androidx.core.graphics.drawable.IconCompat?, CharSequence?, android.app.PendingIntent?);
-    ctor public NotificationCompat.Action.Builder(int, CharSequence?, android.app.PendingIntent?);
-    ctor public NotificationCompat.Action.Builder(androidx.core.app.NotificationCompat.Action);
-    method public androidx.core.app.NotificationCompat.Action.Builder addExtras(android.os.Bundle?);
-    method public androidx.core.app.NotificationCompat.Action.Builder addRemoteInput(androidx.core.app.RemoteInput?);
-    method public androidx.core.app.NotificationCompat.Action build();
-    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Extender);
-    method @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.app.NotificationCompat.Action.Builder fromAndroidAction(android.app.Notification.Action);
-    method public android.os.Bundle getExtras();
-    method public androidx.core.app.NotificationCompat.Action.Builder setAllowGeneratedReplies(boolean);
-    method public androidx.core.app.NotificationCompat.Action.Builder setAuthenticationRequired(boolean);
-    method public androidx.core.app.NotificationCompat.Action.Builder setContextual(boolean);
-    method public androidx.core.app.NotificationCompat.Action.Builder setSemanticAction(@androidx.core.app.NotificationCompat.Action.SemanticAction int);
-    method public androidx.core.app.NotificationCompat.Action.Builder setShowsUserInterface(boolean);
-  }
-
-  public static interface NotificationCompat.Action.Extender {
-    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Builder);
-  }
-
-  @IntDef({androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_NONE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_REPLY, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_UNREAD, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_DELETE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_ARCHIVE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MUTE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_UNMUTE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_THUMBS_UP, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_THUMBS_DOWN, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_CALL}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.Action.SemanticAction {
-  }
-
-  public static final class NotificationCompat.Action.WearableExtender implements androidx.core.app.NotificationCompat.Action.Extender {
-    ctor public NotificationCompat.Action.WearableExtender();
-    ctor public NotificationCompat.Action.WearableExtender(androidx.core.app.NotificationCompat.Action);
-    method public androidx.core.app.NotificationCompat.Action.WearableExtender clone();
-    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Builder);
-    method @Deprecated public CharSequence? getCancelLabel();
-    method @Deprecated public CharSequence? getConfirmLabel();
-    method public boolean getHintDisplayActionInline();
-    method public boolean getHintLaunchesActivity();
-    method @Deprecated public CharSequence? getInProgressLabel();
-    method public boolean isAvailableOffline();
-    method public androidx.core.app.NotificationCompat.Action.WearableExtender setAvailableOffline(boolean);
-    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setCancelLabel(CharSequence?);
-    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setConfirmLabel(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Action.WearableExtender setHintDisplayActionInline(boolean);
-    method public androidx.core.app.NotificationCompat.Action.WearableExtender setHintLaunchesActivity(boolean);
-    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setInProgressLabel(CharSequence?);
-  }
-
-  @IntDef({androidx.core.app.NotificationCompat.BADGE_ICON_NONE, androidx.core.app.NotificationCompat.BADGE_ICON_SMALL, androidx.core.app.NotificationCompat.BADGE_ICON_LARGE}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.BadgeIconType {
-  }
-
-  public static class NotificationCompat.BigPictureStyle extends androidx.core.app.NotificationCompat.Style {
-    ctor public NotificationCompat.BigPictureStyle();
-    ctor public NotificationCompat.BigPictureStyle(androidx.core.app.NotificationCompat.Builder?);
-    method public androidx.core.app.NotificationCompat.BigPictureStyle bigLargeIcon(android.graphics.Bitmap?);
-    method public androidx.core.app.NotificationCompat.BigPictureStyle bigPicture(android.graphics.Bitmap?);
-    method public androidx.core.app.NotificationCompat.BigPictureStyle setBigContentTitle(CharSequence?);
-    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle setContentDescription(CharSequence?);
-    method public androidx.core.app.NotificationCompat.BigPictureStyle setSummaryText(CharSequence?);
-    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle showBigPictureWhenCollapsed(boolean);
-  }
-
-  public static class NotificationCompat.BigTextStyle extends androidx.core.app.NotificationCompat.Style {
-    ctor public NotificationCompat.BigTextStyle();
-    ctor public NotificationCompat.BigTextStyle(androidx.core.app.NotificationCompat.Builder?);
-    method public androidx.core.app.NotificationCompat.BigTextStyle bigText(CharSequence?);
-    method public androidx.core.app.NotificationCompat.BigTextStyle setBigContentTitle(CharSequence?);
-    method public androidx.core.app.NotificationCompat.BigTextStyle setSummaryText(CharSequence?);
-  }
-
-  public static final class NotificationCompat.BubbleMetadata {
-    method public static androidx.core.app.NotificationCompat.BubbleMetadata? fromPlatform(android.app.Notification.BubbleMetadata?);
-    method public boolean getAutoExpandBubble();
-    method public android.app.PendingIntent? getDeleteIntent();
-    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getDesiredHeight();
-    method @DimenRes public int getDesiredHeightResId();
-    method public androidx.core.graphics.drawable.IconCompat? getIcon();
-    method public android.app.PendingIntent? getIntent();
-    method public String? getShortcutId();
-    method public boolean isNotificationSuppressed();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setFlags(int);
-    method public static android.app.Notification.BubbleMetadata? toPlatform(androidx.core.app.NotificationCompat.BubbleMetadata?);
-  }
-
-  public static final class NotificationCompat.BubbleMetadata.Builder {
-    ctor @Deprecated public NotificationCompat.BubbleMetadata.Builder();
-    ctor @RequiresApi(30) public NotificationCompat.BubbleMetadata.Builder(String);
-    ctor public NotificationCompat.BubbleMetadata.Builder(android.app.PendingIntent, androidx.core.graphics.drawable.IconCompat);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata build();
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setAutoExpandBubble(boolean);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDeleteIntent(android.app.PendingIntent?);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDesiredHeight(@Dimension(unit=androidx.annotation.Dimension.DP) int);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setIcon(androidx.core.graphics.drawable.IconCompat);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setIntent(android.app.PendingIntent);
-    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setSuppressNotification(boolean);
-  }
-
-  public static class NotificationCompat.Builder {
-    ctor @RequiresApi(19) public NotificationCompat.Builder(android.content.Context, android.app.Notification);
-    ctor public NotificationCompat.Builder(android.content.Context, String);
-    ctor @Deprecated public NotificationCompat.Builder(android.content.Context);
-    method public androidx.core.app.NotificationCompat.Builder addAction(int, CharSequence?, android.app.PendingIntent?);
-    method public androidx.core.app.NotificationCompat.Builder addAction(androidx.core.app.NotificationCompat.Action?);
-    method public androidx.core.app.NotificationCompat.Builder addExtras(android.os.Bundle?);
-    method @RequiresApi(21) public androidx.core.app.NotificationCompat.Builder addInvisibleAction(int, CharSequence?, android.app.PendingIntent?);
-    method @RequiresApi(21) public androidx.core.app.NotificationCompat.Builder addInvisibleAction(androidx.core.app.NotificationCompat.Action?);
-    method @Deprecated public androidx.core.app.NotificationCompat.Builder addPerson(String?);
-    method public androidx.core.app.NotificationCompat.Builder addPerson(androidx.core.app.Person?);
-    method public android.app.Notification build();
-    method public androidx.core.app.NotificationCompat.Builder clearActions();
-    method public androidx.core.app.NotificationCompat.Builder clearInvisibleActions();
-    method public androidx.core.app.NotificationCompat.Builder clearPeople();
-    method public android.widget.RemoteViews? createBigContentView();
-    method public android.widget.RemoteViews? createContentView();
-    method public android.widget.RemoteViews? createHeadsUpContentView();
-    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Extender);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews! getBigContentView();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.core.app.NotificationCompat.BubbleMetadata? getBubbleMetadata();
-    method @ColorInt @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int getColor();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews! getContentView();
-    method public android.os.Bundle getExtras();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int getForegroundServiceBehavior();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews! getHeadsUpContentView();
-    method @Deprecated public android.app.Notification getNotification();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int getPriority();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public long getWhenIfShowing();
-    method protected static CharSequence? limitCharSequenceLength(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Builder setAllowSystemGeneratedContextualActions(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setAutoCancel(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setBadgeIconType(@androidx.core.app.NotificationCompat.BadgeIconType int);
-    method public androidx.core.app.NotificationCompat.Builder setBubbleMetadata(androidx.core.app.NotificationCompat.BubbleMetadata?);
-    method public androidx.core.app.NotificationCompat.Builder setCategory(String?);
-    method public androidx.core.app.NotificationCompat.Builder setChannelId(String);
-    method @RequiresApi(24) public androidx.core.app.NotificationCompat.Builder setChronometerCountDown(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setColor(@ColorInt int);
-    method public androidx.core.app.NotificationCompat.Builder setColorized(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setContent(android.widget.RemoteViews?);
-    method public androidx.core.app.NotificationCompat.Builder setContentInfo(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Builder setContentIntent(android.app.PendingIntent?);
-    method public androidx.core.app.NotificationCompat.Builder setContentText(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Builder setContentTitle(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Builder setCustomBigContentView(android.widget.RemoteViews?);
-    method public androidx.core.app.NotificationCompat.Builder setCustomContentView(android.widget.RemoteViews?);
-    method public androidx.core.app.NotificationCompat.Builder setCustomHeadsUpContentView(android.widget.RemoteViews?);
-    method public androidx.core.app.NotificationCompat.Builder setDefaults(int);
-    method public androidx.core.app.NotificationCompat.Builder setDeleteIntent(android.app.PendingIntent?);
-    method public androidx.core.app.NotificationCompat.Builder setExtras(android.os.Bundle?);
-    method public androidx.core.app.NotificationCompat.Builder setForegroundServiceBehavior(@androidx.core.app.NotificationCompat.ServiceNotificationBehavior int);
-    method public androidx.core.app.NotificationCompat.Builder setFullScreenIntent(android.app.PendingIntent?, boolean);
-    method public androidx.core.app.NotificationCompat.Builder setGroup(String?);
-    method public androidx.core.app.NotificationCompat.Builder setGroupAlertBehavior(@androidx.core.app.NotificationCompat.GroupAlertBehavior int);
-    method public androidx.core.app.NotificationCompat.Builder setGroupSummary(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setLargeIcon(android.graphics.Bitmap?);
-    method public androidx.core.app.NotificationCompat.Builder setLights(@ColorInt int, int, int);
-    method public androidx.core.app.NotificationCompat.Builder setLocalOnly(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setLocusId(androidx.core.content.LocusIdCompat?);
-    method @Deprecated public androidx.core.app.NotificationCompat.Builder setNotificationSilent();
-    method public androidx.core.app.NotificationCompat.Builder setNumber(int);
-    method public androidx.core.app.NotificationCompat.Builder setOngoing(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setOnlyAlertOnce(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setPriority(int);
-    method public androidx.core.app.NotificationCompat.Builder setProgress(int, int, boolean);
-    method public androidx.core.app.NotificationCompat.Builder setPublicVersion(android.app.Notification?);
-    method public androidx.core.app.NotificationCompat.Builder setRemoteInputHistory(CharSequence![]?);
-    method public androidx.core.app.NotificationCompat.Builder setSettingsText(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Builder setShortcutId(String?);
-    method public androidx.core.app.NotificationCompat.Builder setShortcutInfo(androidx.core.content.pm.ShortcutInfoCompat?);
-    method public androidx.core.app.NotificationCompat.Builder setShowWhen(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setSilent(boolean);
-    method @RequiresApi(23) public androidx.core.app.NotificationCompat.Builder setSmallIcon(androidx.core.graphics.drawable.IconCompat);
-    method public androidx.core.app.NotificationCompat.Builder setSmallIcon(int);
-    method public androidx.core.app.NotificationCompat.Builder setSmallIcon(int, int);
-    method public androidx.core.app.NotificationCompat.Builder setSortKey(String?);
-    method public androidx.core.app.NotificationCompat.Builder setSound(android.net.Uri?);
-    method public androidx.core.app.NotificationCompat.Builder setSound(android.net.Uri?, @androidx.core.app.NotificationCompat.StreamType int);
-    method public androidx.core.app.NotificationCompat.Builder setStyle(androidx.core.app.NotificationCompat.Style?);
-    method public androidx.core.app.NotificationCompat.Builder setSubText(CharSequence?);
-    method public androidx.core.app.NotificationCompat.Builder setTicker(CharSequence?);
-    method @Deprecated public androidx.core.app.NotificationCompat.Builder setTicker(CharSequence?, android.widget.RemoteViews?);
-    method public androidx.core.app.NotificationCompat.Builder setTimeoutAfter(long);
-    method public androidx.core.app.NotificationCompat.Builder setUsesChronometer(boolean);
-    method public androidx.core.app.NotificationCompat.Builder setVibrate(long[]?);
-    method public androidx.core.app.NotificationCompat.Builder setVisibility(@androidx.core.app.NotificationCompat.NotificationVisibility int);
-    method public androidx.core.app.NotificationCompat.Builder setWhen(long);
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public java.util.ArrayList<androidx.core.app.NotificationCompat.Action!>! mActions;
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.content.Context! mContext;
-    field @Deprecated public java.util.ArrayList<java.lang.String!>! mPeople;
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public java.util.ArrayList<androidx.core.app.Person!> mPersonList;
-  }
-
-  public static final class NotificationCompat.CarExtender implements androidx.core.app.NotificationCompat.Extender {
-    ctor public NotificationCompat.CarExtender();
-    ctor public NotificationCompat.CarExtender(android.app.Notification);
-    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
-    method @ColorInt public int getColor();
-    method public android.graphics.Bitmap? getLargeIcon();
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation? getUnreadConversation();
-    method public androidx.core.app.NotificationCompat.CarExtender setColor(@ColorInt int);
-    method public androidx.core.app.NotificationCompat.CarExtender setLargeIcon(android.graphics.Bitmap?);
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender setUnreadConversation(androidx.core.app.NotificationCompat.CarExtender.UnreadConversation?);
-  }
-
-  @Deprecated public static class NotificationCompat.CarExtender.UnreadConversation {
-    method @Deprecated public long getLatestTimestamp();
-    method @Deprecated public String![]? getMessages();
-    method @Deprecated public String? getParticipant();
-    method @Deprecated public String![]? getParticipants();
-    method @Deprecated public android.app.PendingIntent? getReadPendingIntent();
-    method @Deprecated public androidx.core.app.RemoteInput? getRemoteInput();
-    method @Deprecated public android.app.PendingIntent? getReplyPendingIntent();
-  }
-
-  @Deprecated public static class NotificationCompat.CarExtender.UnreadConversation.Builder {
-    ctor @Deprecated public NotificationCompat.CarExtender.UnreadConversation.Builder(String);
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder addMessage(String?);
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation build();
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setLatestTimestamp(long);
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReadPendingIntent(android.app.PendingIntent?);
-    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReplyAction(android.app.PendingIntent?, androidx.core.app.RemoteInput?);
-  }
-
-  public static class NotificationCompat.DecoratedCustomViewStyle extends androidx.core.app.NotificationCompat.Style {
-    ctor public NotificationCompat.DecoratedCustomViewStyle();
-  }
-
-  public static interface NotificationCompat.Extender {
-    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
-  }
-
-  @IntDef({androidx.core.app.NotificationCompat.GROUP_ALERT_ALL, androidx.core.app.NotificationCompat.GROUP_ALERT_SUMMARY, androidx.core.app.NotificationCompat.GROUP_ALERT_CHILDREN}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.GroupAlertBehavior {
-  }
-
-  public static class NotificationCompat.InboxStyle extends androidx.core.app.NotificationCompat.Style {
-    ctor public NotificationCompat.InboxStyle();
-    ctor public NotificationCompat.InboxStyle(androidx.core.app.NotificationCompat.Builder?);
-    method public androidx.core.app.NotificationCompat.InboxStyle addLine(CharSequence?);
-    method public androidx.core.app.NotificationCompat.InboxStyle setBigContentTitle(CharSequence?);
-    method public androidx.core.app.NotificationCompat.InboxStyle setSummaryText(CharSequence?);
-  }
-
-  public static class NotificationCompat.MessagingStyle extends androidx.core.app.NotificationCompat.Style {
-    ctor @Deprecated public NotificationCompat.MessagingStyle(CharSequence);
-    ctor public NotificationCompat.MessagingStyle(androidx.core.app.Person);
-    method public androidx.core.app.NotificationCompat.MessagingStyle addHistoricMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message?);
-    method @Deprecated public androidx.core.app.NotificationCompat.MessagingStyle addMessage(CharSequence?, long, CharSequence?);
-    method public androidx.core.app.NotificationCompat.MessagingStyle addMessage(CharSequence?, long, androidx.core.app.Person?);
-    method public androidx.core.app.NotificationCompat.MessagingStyle addMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message?);
-    method public static androidx.core.app.NotificationCompat.MessagingStyle? extractMessagingStyleFromNotification(android.app.Notification);
-    method public CharSequence? getConversationTitle();
-    method public java.util.List<androidx.core.app.NotificationCompat.MessagingStyle.Message!> getHistoricMessages();
-    method public java.util.List<androidx.core.app.NotificationCompat.MessagingStyle.Message!> getMessages();
-    method public androidx.core.app.Person getUser();
-    method @Deprecated public CharSequence? getUserDisplayName();
-    method public boolean isGroupConversation();
-    method public androidx.core.app.NotificationCompat.MessagingStyle setConversationTitle(CharSequence?);
-    method public androidx.core.app.NotificationCompat.MessagingStyle setGroupConversation(boolean);
-    field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
-  }
-
-  public static final class NotificationCompat.MessagingStyle.Message {
-    ctor public NotificationCompat.MessagingStyle.Message(CharSequence?, long, androidx.core.app.Person?);
-    ctor @Deprecated public NotificationCompat.MessagingStyle.Message(CharSequence?, long, CharSequence?);
-    method public String? getDataMimeType();
-    method public android.net.Uri? getDataUri();
-    method public android.os.Bundle getExtras();
-    method public androidx.core.app.Person? getPerson();
-    method @Deprecated public CharSequence? getSender();
-    method public CharSequence? getText();
-    method public long getTimestamp();
-    method public androidx.core.app.NotificationCompat.MessagingStyle.Message setData(String?, android.net.Uri?);
-  }
-
-  @IntDef({androidx.core.app.NotificationCompat.VISIBILITY_PUBLIC, androidx.core.app.NotificationCompat.VISIBILITY_PRIVATE, androidx.core.app.NotificationCompat.VISIBILITY_SECRET}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.NotificationVisibility {
-  }
-
-  @IntDef({androidx.core.app.NotificationCompat.FOREGROUND_SERVICE_DEFAULT, androidx.core.app.NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE, androidx.core.app.NotificationCompat.FOREGROUND_SERVICE_DEFERRED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.ServiceNotificationBehavior {
-  }
-
-  @IntDef({android.media.AudioManager.STREAM_VOICE_CALL, android.media.AudioManager.STREAM_SYSTEM, android.media.AudioManager.STREAM_RING, android.media.AudioManager.STREAM_MUSIC, android.media.AudioManager.STREAM_ALARM, android.media.AudioManager.STREAM_NOTIFICATION, android.media.AudioManager.STREAM_DTMF, android.media.AudioManager.STREAM_ACCESSIBILITY}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.StreamType {
-  }
-
-  public abstract static class NotificationCompat.Style {
-    ctor public NotificationCompat.Style();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void addCompatExtras(android.os.Bundle);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void apply(androidx.core.app.NotificationBuilderWithBuilderAccessor!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews applyStandardTemplate(boolean, int, boolean);
-    method public android.app.Notification? build();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void buildIntoRemoteViews(android.widget.RemoteViews!, android.widget.RemoteViews!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected void clearCompatExtraKeys(android.os.Bundle);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.Bitmap! createColoredBitmap(int, int);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean displayCustomViewInline();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.app.NotificationCompat.Style? extractStyleFromNotification(android.app.Notification);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected String? getClassName();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews! makeBigContentView(androidx.core.app.NotificationBuilderWithBuilderAccessor!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews! makeContentView(androidx.core.app.NotificationBuilderWithBuilderAccessor!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.widget.RemoteViews! makeHeadsUpContentView(androidx.core.app.NotificationBuilderWithBuilderAccessor!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected void restoreFromCompatExtras(android.os.Bundle);
-    method public void setBuilder(androidx.core.app.NotificationCompat.Builder?);
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected androidx.core.app.NotificationCompat.Builder! mBuilder;
-  }
-
-  public static final class NotificationCompat.WearableExtender implements androidx.core.app.NotificationCompat.Extender {
-    ctor public NotificationCompat.WearableExtender();
-    ctor public NotificationCompat.WearableExtender(android.app.Notification);
-    method public androidx.core.app.NotificationCompat.WearableExtender addAction(androidx.core.app.NotificationCompat.Action);
-    method public androidx.core.app.NotificationCompat.WearableExtender addActions(java.util.List<androidx.core.app.NotificationCompat.Action!>);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender addPage(android.app.Notification);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender addPages(java.util.List<android.app.Notification!>);
-    method public androidx.core.app.NotificationCompat.WearableExtender clearActions();
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender clearPages();
-    method public androidx.core.app.NotificationCompat.WearableExtender clone();
-    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
-    method public java.util.List<androidx.core.app.NotificationCompat.Action!> getActions();
-    method @Deprecated public android.graphics.Bitmap? getBackground();
-    method public String? getBridgeTag();
-    method public int getContentAction();
-    method @Deprecated public int getContentIcon();
-    method @Deprecated public int getContentIconGravity();
-    method public boolean getContentIntentAvailableOffline();
-    method @Deprecated public int getCustomContentHeight();
-    method @Deprecated public int getCustomSizePreset();
-    method public String? getDismissalId();
-    method @Deprecated public android.app.PendingIntent? getDisplayIntent();
-    method @Deprecated public int getGravity();
-    method @Deprecated public boolean getHintAmbientBigPicture();
-    method @Deprecated public boolean getHintAvoidBackgroundClipping();
-    method public boolean getHintContentIntentLaunchesActivity();
-    method @Deprecated public boolean getHintHideIcon();
-    method @Deprecated public int getHintScreenTimeout();
-    method @Deprecated public boolean getHintShowBackgroundOnly();
-    method @Deprecated public java.util.List<android.app.Notification!> getPages();
-    method public boolean getStartScrollBottom();
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setBackground(android.graphics.Bitmap?);
-    method public androidx.core.app.NotificationCompat.WearableExtender setBridgeTag(String?);
-    method public androidx.core.app.NotificationCompat.WearableExtender setContentAction(int);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setContentIcon(int);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setContentIconGravity(int);
-    method public androidx.core.app.NotificationCompat.WearableExtender setContentIntentAvailableOffline(boolean);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setCustomContentHeight(int);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setCustomSizePreset(int);
-    method public androidx.core.app.NotificationCompat.WearableExtender setDismissalId(String?);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setDisplayIntent(android.app.PendingIntent?);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setGravity(int);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintAmbientBigPicture(boolean);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintAvoidBackgroundClipping(boolean);
-    method public androidx.core.app.NotificationCompat.WearableExtender setHintContentIntentLaunchesActivity(boolean);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintHideIcon(boolean);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintScreenTimeout(int);
-    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintShowBackgroundOnly(boolean);
-    method public androidx.core.app.NotificationCompat.WearableExtender setStartScrollBottom(boolean);
-    field @Deprecated public static final int SCREEN_TIMEOUT_LONG = -1; // 0xffffffff
-    field @Deprecated public static final int SCREEN_TIMEOUT_SHORT = 0; // 0x0
-    field @Deprecated public static final int SIZE_DEFAULT = 0; // 0x0
-    field @Deprecated public static final int SIZE_FULL_SCREEN = 5; // 0x5
-    field @Deprecated public static final int SIZE_LARGE = 4; // 0x4
-    field @Deprecated public static final int SIZE_MEDIUM = 3; // 0x3
-    field @Deprecated public static final int SIZE_SMALL = 2; // 0x2
-    field @Deprecated public static final int SIZE_XSMALL = 1; // 0x1
-    field public static final int UNSET_ACTION_INDEX = -1; // 0xffffffff
-  }
-
-  public final class NotificationCompatExtras {
-    field public static final String EXTRA_ACTION_EXTRAS = "android.support.actionExtras";
-    field public static final String EXTRA_GROUP_KEY = "android.support.groupKey";
-    field public static final String EXTRA_GROUP_SUMMARY = "android.support.isGroupSummary";
-    field public static final String EXTRA_LOCAL_ONLY = "android.support.localOnly";
-    field public static final String EXTRA_REMOTE_INPUTS = "android.support.remoteInputs";
-    field public static final String EXTRA_SORT_KEY = "android.support.sortKey";
-  }
-
-  public abstract class NotificationCompatSideChannelService extends android.app.Service {
-    ctor public NotificationCompatSideChannelService();
-    method public abstract void cancel(String!, int, String!);
-    method public abstract void cancelAll(String!);
-    method public abstract void notify(String!, int, String!, android.app.Notification!);
-    method public android.os.IBinder! onBind(android.content.Intent!);
-  }
-
-  public final class NotificationManagerCompat {
-    method public boolean areNotificationsEnabled();
-    method public void cancel(int);
-    method public void cancel(String?, int);
-    method public void cancelAll();
-    method public void createNotificationChannel(android.app.NotificationChannel);
-    method public void createNotificationChannel(androidx.core.app.NotificationChannelCompat);
-    method public void createNotificationChannelGroup(android.app.NotificationChannelGroup);
-    method public void createNotificationChannelGroup(androidx.core.app.NotificationChannelGroupCompat);
-    method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup!>);
-    method public void createNotificationChannelGroupsCompat(java.util.List<androidx.core.app.NotificationChannelGroupCompat!>);
-    method public void createNotificationChannels(java.util.List<android.app.NotificationChannel!>);
-    method public void createNotificationChannelsCompat(java.util.List<androidx.core.app.NotificationChannelCompat!>);
-    method public void deleteNotificationChannel(String);
-    method public void deleteNotificationChannelGroup(String);
-    method public void deleteUnlistedNotificationChannels(java.util.Collection<java.lang.String!>);
-    method public static androidx.core.app.NotificationManagerCompat from(android.content.Context);
-    method public static java.util.Set<java.lang.String!> getEnabledListenerPackages(android.content.Context);
-    method public int getImportance();
-    method public android.app.NotificationChannel? getNotificationChannel(String);
-    method public android.app.NotificationChannel? getNotificationChannel(String, String);
-    method public androidx.core.app.NotificationChannelCompat? getNotificationChannelCompat(String);
-    method public androidx.core.app.NotificationChannelCompat? getNotificationChannelCompat(String, String);
-    method public android.app.NotificationChannelGroup? getNotificationChannelGroup(String);
-    method public androidx.core.app.NotificationChannelGroupCompat? getNotificationChannelGroupCompat(String);
-    method public java.util.List<android.app.NotificationChannelGroup!> getNotificationChannelGroups();
-    method public java.util.List<androidx.core.app.NotificationChannelGroupCompat!> getNotificationChannelGroupsCompat();
-    method public java.util.List<android.app.NotificationChannel!> getNotificationChannels();
-    method public java.util.List<androidx.core.app.NotificationChannelCompat!> getNotificationChannelsCompat();
-    method public void notify(int, android.app.Notification);
-    method public void notify(String?, int, android.app.Notification);
-    field public static final String ACTION_BIND_SIDE_CHANNEL = "android.support.BIND_NOTIFICATION_SIDE_CHANNEL";
-    field public static final String EXTRA_USE_SIDE_CHANNEL = "android.support.useSideChannel";
-    field public static final int IMPORTANCE_DEFAULT = 3; // 0x3
-    field public static final int IMPORTANCE_HIGH = 4; // 0x4
-    field public static final int IMPORTANCE_LOW = 2; // 0x2
-    field public static final int IMPORTANCE_MAX = 5; // 0x5
-    field public static final int IMPORTANCE_MIN = 1; // 0x1
-    field public static final int IMPORTANCE_NONE = 0; // 0x0
-    field public static final int IMPORTANCE_UNSPECIFIED = -1000; // 0xfffffc18
-  }
-
-  public interface OnMultiWindowModeChangedProvider {
-    method public void addOnMultiWindowModeChangedListener(androidx.core.util.Consumer<androidx.core.app.MultiWindowModeChangedInfo!>);
-    method public void removeOnMultiWindowModeChangedListener(androidx.core.util.Consumer<androidx.core.app.MultiWindowModeChangedInfo!>);
-  }
-
-  public interface OnNewIntentProvider {
-    method public void addOnNewIntentListener(androidx.core.util.Consumer<android.content.Intent!>);
-    method public void removeOnNewIntentListener(androidx.core.util.Consumer<android.content.Intent!>);
-  }
-
-  public interface OnPictureInPictureModeChangedProvider {
-    method public void addOnPictureInPictureModeChangedListener(androidx.core.util.Consumer<androidx.core.app.PictureInPictureModeChangedInfo!>);
-    method public void removeOnPictureInPictureModeChangedListener(androidx.core.util.Consumer<androidx.core.app.PictureInPictureModeChangedInfo!>);
-  }
-
-  public class Person {
-    method @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.app.Person fromAndroidPerson(android.app.Person);
-    method public static androidx.core.app.Person fromBundle(android.os.Bundle);
-    method @RequiresApi(22) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.app.Person fromPersistableBundle(android.os.PersistableBundle);
-    method public androidx.core.graphics.drawable.IconCompat? getIcon();
-    method public String? getKey();
-    method public CharSequence? getName();
-    method public String? getUri();
-    method public boolean isBot();
-    method public boolean isImportant();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public String resolveToLegacyUri();
-    method @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.app.Person toAndroidPerson();
-    method public androidx.core.app.Person.Builder toBuilder();
-    method public android.os.Bundle toBundle();
-    method @RequiresApi(22) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.os.PersistableBundle toPersistableBundle();
-  }
-
-  public static class Person.Builder {
-    ctor public Person.Builder();
-    method public androidx.core.app.Person build();
-    method public androidx.core.app.Person.Builder setBot(boolean);
-    method public androidx.core.app.Person.Builder setIcon(androidx.core.graphics.drawable.IconCompat?);
-    method public androidx.core.app.Person.Builder setImportant(boolean);
-    method public androidx.core.app.Person.Builder setKey(String?);
-    method public androidx.core.app.Person.Builder setName(CharSequence?);
-    method public androidx.core.app.Person.Builder setUri(String?);
-  }
-
-  public final class PictureInPictureModeChangedInfo {
-    ctor public PictureInPictureModeChangedInfo(boolean);
-    ctor @RequiresApi(26) public PictureInPictureModeChangedInfo(boolean, android.content.res.Configuration);
-    method @RequiresApi(26) public android.content.res.Configuration getNewConfig();
-    method public boolean isInPictureInPictureMode();
-  }
-
-  @androidx.versionedparcelable.VersionedParcelize(jetifyAs="android.support.v4.app.RemoteActionCompat") public final class RemoteActionCompat implements androidx.versionedparcelable.VersionedParcelable {
-    ctor public RemoteActionCompat(androidx.core.graphics.drawable.IconCompat, CharSequence, CharSequence, android.app.PendingIntent);
-    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public RemoteActionCompat();
-    ctor public RemoteActionCompat(androidx.core.app.RemoteActionCompat);
-    method @RequiresApi(26) public static androidx.core.app.RemoteActionCompat createFromRemoteAction(android.app.RemoteAction);
-    method public android.app.PendingIntent getActionIntent();
-    method public CharSequence getContentDescription();
-    method public androidx.core.graphics.drawable.IconCompat getIcon();
-    method public CharSequence getTitle();
-    method public boolean isEnabled();
-    method public void setEnabled(boolean);
-    method public void setShouldShowIcon(boolean);
-    method public boolean shouldShowIcon();
-    method @RequiresApi(26) public android.app.RemoteAction toRemoteAction();
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(4) public android.app.PendingIntent mActionIntent;
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(3) public CharSequence mContentDescription;
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(5) public boolean mEnabled;
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(1) public androidx.core.graphics.drawable.IconCompat mIcon;
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(6) public boolean mShouldShowIcon;
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @androidx.versionedparcelable.ParcelField(2) public CharSequence mTitle;
-  }
-
-  public final class RemoteInput {
-    method public static void addDataResultToIntent(androidx.core.app.RemoteInput, android.content.Intent, java.util.Map<java.lang.String!,android.net.Uri!>);
-    method public static void addResultsToIntent(androidx.core.app.RemoteInput![], android.content.Intent, android.os.Bundle);
-    method public boolean getAllowFreeFormInput();
-    method public java.util.Set<java.lang.String!>? getAllowedDataTypes();
-    method public CharSequence![]? getChoices();
-    method public static java.util.Map<java.lang.String!,android.net.Uri!>? getDataResultsFromIntent(android.content.Intent, String);
-    method @androidx.core.app.RemoteInput.EditChoicesBeforeSending public int getEditChoicesBeforeSending();
-    method public android.os.Bundle getExtras();
-    method public CharSequence? getLabel();
-    method public String getResultKey();
-    method public static android.os.Bundle? getResultsFromIntent(android.content.Intent);
-    method @androidx.core.app.RemoteInput.Source public static int getResultsSource(android.content.Intent);
-    method public boolean isDataOnly();
-    method public static void setResultsSource(android.content.Intent, @androidx.core.app.RemoteInput.Source int);
-    field public static final int EDIT_CHOICES_BEFORE_SENDING_AUTO = 0; // 0x0
-    field public static final int EDIT_CHOICES_BEFORE_SENDING_DISABLED = 1; // 0x1
-    field public static final int EDIT_CHOICES_BEFORE_SENDING_ENABLED = 2; // 0x2
-    field public static final String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
-    field public static final String RESULTS_CLIP_LABEL = "android.remoteinput.results";
-    field public static final int SOURCE_CHOICE = 1; // 0x1
-    field public static final int SOURCE_FREE_FORM_INPUT = 0; // 0x0
-  }
-
-  public static final class RemoteInput.Builder {
-    ctor public RemoteInput.Builder(String);
-    method public androidx.core.app.RemoteInput.Builder addExtras(android.os.Bundle);
-    method public androidx.core.app.RemoteInput build();
-    method public android.os.Bundle getExtras();
-    method public androidx.core.app.RemoteInput.Builder setAllowDataType(String, boolean);
-    method public androidx.core.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
-    method public androidx.core.app.RemoteInput.Builder setChoices(CharSequence![]?);
-    method public androidx.core.app.RemoteInput.Builder setEditChoicesBeforeSending(@androidx.core.app.RemoteInput.EditChoicesBeforeSending int);
-    method public androidx.core.app.RemoteInput.Builder setLabel(CharSequence?);
-  }
-
-  @IntDef({androidx.core.app.RemoteInput.EDIT_CHOICES_BEFORE_SENDING_AUTO, androidx.core.app.RemoteInput.EDIT_CHOICES_BEFORE_SENDING_DISABLED, androidx.core.app.RemoteInput.EDIT_CHOICES_BEFORE_SENDING_ENABLED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RemoteInput.EditChoicesBeforeSending {
-  }
-
-  @IntDef({androidx.core.app.RemoteInput.SOURCE_FREE_FORM_INPUT, androidx.core.app.RemoteInput.SOURCE_CHOICE}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface RemoteInput.Source {
-  }
-
-  public final class ServiceCompat {
-    method public static void stopForeground(android.app.Service, @androidx.core.app.ServiceCompat.StopForegroundFlags int);
-    field public static final int START_STICKY = 1; // 0x1
-    field public static final int STOP_FOREGROUND_DETACH = 2; // 0x2
-    field public static final int STOP_FOREGROUND_REMOVE = 1; // 0x1
-  }
-
-  @IntDef(flag=true, value={androidx.core.app.ServiceCompat.STOP_FOREGROUND_REMOVE, androidx.core.app.ServiceCompat.STOP_FOREGROUND_DETACH}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ServiceCompat.StopForegroundFlags {
-  }
-
-  public final class ShareCompat {
-    method @Deprecated public static void configureMenuItem(android.view.MenuItem, androidx.core.app.ShareCompat.IntentBuilder);
-    method @Deprecated public static void configureMenuItem(android.view.Menu, @IdRes int, androidx.core.app.ShareCompat.IntentBuilder);
-    method public static android.content.ComponentName? getCallingActivity(android.app.Activity);
-    method public static String? getCallingPackage(android.app.Activity);
-    field public static final String EXTRA_CALLING_ACTIVITY = "androidx.core.app.EXTRA_CALLING_ACTIVITY";
-    field public static final String EXTRA_CALLING_ACTIVITY_INTEROP = "android.support.v4.app.EXTRA_CALLING_ACTIVITY";
-    field public static final String EXTRA_CALLING_PACKAGE = "androidx.core.app.EXTRA_CALLING_PACKAGE";
-    field public static final String EXTRA_CALLING_PACKAGE_INTEROP = "android.support.v4.app.EXTRA_CALLING_PACKAGE";
-  }
-
-  public static class ShareCompat.IntentBuilder {
-    ctor public ShareCompat.IntentBuilder(android.content.Context);
-    method public androidx.core.app.ShareCompat.IntentBuilder addEmailBcc(String);
-    method public androidx.core.app.ShareCompat.IntentBuilder addEmailBcc(String![]);
-    method public androidx.core.app.ShareCompat.IntentBuilder addEmailCc(String);
-    method public androidx.core.app.ShareCompat.IntentBuilder addEmailCc(String![]);
-    method public androidx.core.app.ShareCompat.IntentBuilder addEmailTo(String);
-    method public androidx.core.app.ShareCompat.IntentBuilder addEmailTo(String![]);
-    method public androidx.core.app.ShareCompat.IntentBuilder addStream(android.net.Uri);
-    method public android.content.Intent createChooserIntent();
-    method @Deprecated public static androidx.core.app.ShareCompat.IntentBuilder from(android.app.Activity);
-    method public android.content.Intent getIntent();
-    method public androidx.core.app.ShareCompat.IntentBuilder setChooserTitle(CharSequence?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setChooserTitle(@StringRes int);
-    method public androidx.core.app.ShareCompat.IntentBuilder setEmailBcc(String![]?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setEmailCc(String![]?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setEmailTo(String![]?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setHtmlText(String?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setStream(android.net.Uri?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setSubject(String?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setText(CharSequence?);
-    method public androidx.core.app.ShareCompat.IntentBuilder setType(String?);
-    method public void startChooser();
-  }
-
-  public static class ShareCompat.IntentReader {
-    ctor public ShareCompat.IntentReader(android.app.Activity);
-    ctor public ShareCompat.IntentReader(android.content.Context, android.content.Intent);
-    method @Deprecated public static androidx.core.app.ShareCompat.IntentReader from(android.app.Activity);
-    method public android.content.ComponentName? getCallingActivity();
-    method public android.graphics.drawable.Drawable? getCallingActivityIcon();
-    method public android.graphics.drawable.Drawable? getCallingApplicationIcon();
-    method public CharSequence? getCallingApplicationLabel();
-    method public String? getCallingPackage();
-    method public String![]? getEmailBcc();
-    method public String![]? getEmailCc();
-    method public String![]? getEmailTo();
-    method public String? getHtmlText();
-    method public android.net.Uri? getStream();
-    method public android.net.Uri? getStream(int);
-    method public int getStreamCount();
-    method public String? getSubject();
-    method public CharSequence? getText();
-    method public String? getType();
-    method public boolean isMultipleShare();
-    method public boolean isShareIntent();
-    method public boolean isSingleShare();
-  }
-
-  public abstract class SharedElementCallback {
-    ctor public SharedElementCallback();
-    method public android.os.Parcelable! onCaptureSharedElementSnapshot(android.view.View!, android.graphics.Matrix!, android.graphics.RectF!);
-    method public android.view.View! onCreateSnapshotView(android.content.Context!, android.os.Parcelable!);
-    method public void onMapSharedElements(java.util.List<java.lang.String!>!, java.util.Map<java.lang.String!,android.view.View!>!);
-    method public void onRejectSharedElements(java.util.List<android.view.View!>!);
-    method public void onSharedElementEnd(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, java.util.List<android.view.View!>!);
-    method public void onSharedElementStart(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, java.util.List<android.view.View!>!);
-    method public void onSharedElementsArrived(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, androidx.core.app.SharedElementCallback.OnSharedElementsReadyListener!);
-  }
-
-  public static interface SharedElementCallback.OnSharedElementsReadyListener {
-    method public void onSharedElementsReady();
-  }
-
-  public final class TaskStackBuilder implements java.lang.Iterable<android.content.Intent> {
-    method public androidx.core.app.TaskStackBuilder addNextIntent(android.content.Intent);
-    method public androidx.core.app.TaskStackBuilder addNextIntentWithParentStack(android.content.Intent);
-    method public androidx.core.app.TaskStackBuilder addParentStack(android.app.Activity);
-    method public androidx.core.app.TaskStackBuilder addParentStack(Class<?>);
-    method public androidx.core.app.TaskStackBuilder addParentStack(android.content.ComponentName);
-    method public static androidx.core.app.TaskStackBuilder create(android.content.Context);
-    method public android.content.Intent? editIntentAt(int);
-    method @Deprecated public static androidx.core.app.TaskStackBuilder! from(android.content.Context!);
-    method @Deprecated public android.content.Intent! getIntent(int);
-    method public int getIntentCount();
-    method public android.content.Intent![] getIntents();
-    method public android.app.PendingIntent? getPendingIntent(int, int);
-    method public android.app.PendingIntent? getPendingIntent(int, int, android.os.Bundle?);
-    method @Deprecated public java.util.Iterator<android.content.Intent!> iterator();
-    method public void startActivities();
-    method public void startActivities(android.os.Bundle?);
-  }
-
-  public static interface TaskStackBuilder.SupportParentable {
-    method public android.content.Intent? getSupportParentActivityIntent();
-  }
-
-}
-
-package androidx.core.content {
-
-  public final class ContentProviderCompat {
-    method public static android.content.Context requireContext(android.content.ContentProvider);
-  }
-
-  public final class ContentResolverCompat {
-    method public static android.database.Cursor? query(android.content.ContentResolver, android.net.Uri, String![]?, String?, String![]?, String?, androidx.core.os.CancellationSignal?);
-  }
-
-  public class ContextCompat {
-    ctor protected ContextCompat();
-    method public static int checkSelfPermission(android.content.Context, String);
-    method public static android.content.Context? createDeviceProtectedStorageContext(android.content.Context);
-    method public static String? getAttributionTag(android.content.Context);
-    method public static java.io.File getCodeCacheDir(android.content.Context);
-    method @ColorInt public static int getColor(android.content.Context, @ColorRes int);
-    method public static android.content.res.ColorStateList? getColorStateList(android.content.Context, @ColorRes int);
-    method public static java.io.File? getDataDir(android.content.Context);
-    method public static android.graphics.drawable.Drawable? getDrawable(android.content.Context, @DrawableRes int);
-    method public static java.io.File![] getExternalCacheDirs(android.content.Context);
-    method public static java.io.File![] getExternalFilesDirs(android.content.Context, String?);
-    method public static java.util.concurrent.Executor getMainExecutor(android.content.Context);
-    method public static java.io.File? getNoBackupFilesDir(android.content.Context);
-    method public static java.io.File![] getObbDirs(android.content.Context);
-    method public static <T> T? getSystemService(android.content.Context, Class<T!>);
-    method public static String? getSystemServiceName(android.content.Context, Class<?>);
-    method public static boolean isDeviceProtectedStorage(android.content.Context);
-    method public static boolean startActivities(android.content.Context, android.content.Intent![]);
-    method public static boolean startActivities(android.content.Context, android.content.Intent![], android.os.Bundle?);
-    method public static void startActivity(android.content.Context, android.content.Intent, android.os.Bundle?);
-    method public static void startForegroundService(android.content.Context, android.content.Intent);
-  }
-
-  public class FileProvider extends android.content.ContentProvider {
-    ctor public FileProvider();
-    ctor protected FileProvider(@XmlRes int);
-    method public int delete(android.net.Uri, String?, String![]?);
-    method public String? getType(android.net.Uri);
-    method public static android.net.Uri! getUriForFile(android.content.Context, String, java.io.File);
-    method public static android.net.Uri getUriForFile(android.content.Context, String, java.io.File, String);
-    method public android.net.Uri! insert(android.net.Uri, android.content.ContentValues);
-    method public boolean onCreate();
-    method public android.database.Cursor query(android.net.Uri, String![]?, String?, String![]?, String?);
-    method public int update(android.net.Uri, android.content.ContentValues, String?, String![]?);
-  }
-
-  public final class IntentCompat {
-    method public static android.content.Intent createManageUnusedAppRestrictionsIntent(android.content.Context, String);
-    method public static android.content.Intent makeMainSelectorActivity(String, String);
-    field public static final String ACTION_CREATE_REMINDER = "android.intent.action.CREATE_REMINDER";
-    field public static final String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
-    field public static final String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
-    field public static final String EXTRA_START_PLAYBACK = "android.intent.extra.START_PLAYBACK";
-    field public static final String EXTRA_TIME = "android.intent.extra.TIME";
-  }
-
-  public final class LocusIdCompat {
-    ctor public LocusIdCompat(String);
-    method public String getId();
-    method @RequiresApi(29) public android.content.LocusId toLocusId();
-    method @RequiresApi(29) public static androidx.core.content.LocusIdCompat toLocusIdCompat(android.content.LocusId);
-  }
-
-  public final class MimeTypeFilter {
-    method public static boolean matches(String?, String);
-    method public static String? matches(String?, String![]);
-    method public static String? matches(String![]?, String);
-    method public static String![] matchesMany(String![]?, String);
-  }
-
-  public interface OnConfigurationChangedProvider {
-    method public void addOnConfigurationChangedListener(androidx.core.util.Consumer<android.content.res.Configuration!>);
-    method public void removeOnConfigurationChangedListener(androidx.core.util.Consumer<android.content.res.Configuration!>);
-  }
-
-  public interface OnTrimMemoryProvider {
-    method public void addOnTrimMemoryListener(androidx.core.util.Consumer<java.lang.Integer!>);
-    method public void removeOnTrimMemoryListener(androidx.core.util.Consumer<java.lang.Integer!>);
-  }
-
-  public final class PackageManagerCompat {
-    method public static com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> getUnusedAppRestrictionsStatus(android.content.Context);
-    field public static final String ACTION_PERMISSION_REVOCATION_SETTINGS = "android.intent.action.AUTO_REVOKE_PERMISSIONS";
-  }
-
-  public final class PermissionChecker {
-    method @androidx.core.content.PermissionChecker.PermissionResult public static int checkCallingOrSelfPermission(android.content.Context, String);
-    method @androidx.core.content.PermissionChecker.PermissionResult public static int checkCallingPermission(android.content.Context, String, String?);
-    method @androidx.core.content.PermissionChecker.PermissionResult public static int checkPermission(android.content.Context, String, int, int, String?);
-    method @androidx.core.content.PermissionChecker.PermissionResult public static int checkSelfPermission(android.content.Context, String);
-    field public static final int PERMISSION_DENIED = -1; // 0xffffffff
-    field public static final int PERMISSION_DENIED_APP_OP = -2; // 0xfffffffe
-    field public static final int PERMISSION_GRANTED = 0; // 0x0
-  }
-
-  @IntDef({androidx.core.content.PermissionChecker.PERMISSION_GRANTED, androidx.core.content.PermissionChecker.PERMISSION_DENIED, androidx.core.content.PermissionChecker.PERMISSION_DENIED_APP_OP}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PermissionChecker.PermissionResult {
-  }
-
-  @Deprecated public final class SharedPreferencesCompat {
-  }
-
-  @Deprecated public static final class SharedPreferencesCompat.EditorCompat {
-    method @Deprecated public void apply(android.content.SharedPreferences.Editor);
-    method @Deprecated public static androidx.core.content.SharedPreferencesCompat.EditorCompat! getInstance();
-  }
-
-  public class UnusedAppRestrictionsBackportCallback {
-    method public void onResult(boolean, boolean) throws android.os.RemoteException;
-  }
-
-  public abstract class UnusedAppRestrictionsBackportService extends android.app.Service {
-    ctor public UnusedAppRestrictionsBackportService();
-    method protected abstract void isPermissionRevocationEnabled(androidx.core.content.UnusedAppRestrictionsBackportCallback);
-    method public android.os.IBinder? onBind(android.content.Intent?);
-    field public static final String ACTION_UNUSED_APP_RESTRICTIONS_BACKPORT_CONNECTION = "android.support.unusedapprestrictions.action.CustomUnusedAppRestrictionsBackportService";
-  }
-
-  public final class UnusedAppRestrictionsConstants {
-    field public static final int API_30 = 4; // 0x4
-    field public static final int API_30_BACKPORT = 3; // 0x3
-    field public static final int API_31 = 5; // 0x5
-    field public static final int DISABLED = 2; // 0x2
-    field public static final int ERROR = 0; // 0x0
-    field public static final int FEATURE_NOT_AVAILABLE = 1; // 0x1
-  }
-
-}
-
-package androidx.core.content.pm {
-
-  @Deprecated public final class ActivityInfoCompat {
-    field @Deprecated public static final int CONFIG_UI_MODE = 512; // 0x200
-  }
-
-  public final class PackageInfoCompat {
-    method public static long getLongVersionCode(android.content.pm.PackageInfo);
-    method public static java.util.List<android.content.pm.Signature!> getSignatures(android.content.pm.PackageManager, String) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public static boolean hasSignatures(android.content.pm.PackageManager, String, @Size(min=1) java.util.Map<byte[]!,java.lang.Integer!>, boolean) throws android.content.pm.PackageManager.NameNotFoundException;
-  }
-
-  public final class PermissionInfoCompat {
-    method public static int getProtection(android.content.pm.PermissionInfo);
-    method public static int getProtectionFlags(android.content.pm.PermissionInfo);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class ShortcutInfoChangeListener {
-    ctor public ShortcutInfoChangeListener();
-    method @AnyThread public void onAllShortcutsRemoved();
-    method @AnyThread public void onShortcutAdded(java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
-    method @AnyThread public void onShortcutRemoved(java.util.List<java.lang.String!>);
-    method @AnyThread public void onShortcutUpdated(java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
-    method @AnyThread public void onShortcutUsageReported(java.util.List<java.lang.String!>);
-  }
-
-  public class ShortcutInfoCompat {
-    method public android.content.ComponentName? getActivity();
-    method public java.util.Set<java.lang.String!>? getCategories();
-    method public CharSequence? getDisabledMessage();
-    method public int getDisabledReason();
-    method @androidx.core.content.pm.ShortcutInfoCompat.Surface public int getExcludedFromSurfaces();
-    method public android.os.PersistableBundle? getExtras();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.core.graphics.drawable.IconCompat! getIcon();
-    method public String getId();
-    method public android.content.Intent getIntent();
-    method public android.content.Intent![] getIntents();
-    method public long getLastChangedTimestamp();
-    method public androidx.core.content.LocusIdCompat? getLocusId();
-    method public CharSequence? getLongLabel();
-    method public String getPackage();
-    method public int getRank();
-    method public CharSequence getShortLabel();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.os.Bundle? getTransientExtras();
-    method public android.os.UserHandle? getUserHandle();
-    method public boolean hasKeyFieldsOnly();
-    method public boolean isCached();
-    method public boolean isDeclaredInManifest();
-    method public boolean isDynamic();
-    method public boolean isEnabled();
-    method public boolean isExcludedFromSurfaces(@androidx.core.content.pm.ShortcutInfoCompat.Surface int);
-    method public boolean isImmutable();
-    method public boolean isPinned();
-    method @RequiresApi(25) public android.content.pm.ShortcutInfo! toShortcutInfo();
-    field public static final int SURFACE_LAUNCHER = 1; // 0x1
-  }
-
-  public static class ShortcutInfoCompat.Builder {
-    ctor public ShortcutInfoCompat.Builder(android.content.Context, String);
-    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public ShortcutInfoCompat.Builder(androidx.core.content.pm.ShortcutInfoCompat);
-    ctor @RequiresApi(25) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public ShortcutInfoCompat.Builder(android.content.Context, android.content.pm.ShortcutInfo);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder addCapabilityBinding(String);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder addCapabilityBinding(String, String, java.util.List<java.lang.String!>);
-    method public androidx.core.content.pm.ShortcutInfoCompat build();
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setActivity(android.content.ComponentName);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setAlwaysBadged();
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setCategories(java.util.Set<java.lang.String!>);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setDisabledMessage(CharSequence);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setExcludedFromSurfaces(int);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setExtras(android.os.PersistableBundle);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIcon(androidx.core.graphics.drawable.IconCompat!);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIntent(android.content.Intent);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIntents(android.content.Intent![]);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIsConversation();
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLocusId(androidx.core.content.LocusIdCompat?);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLabel(CharSequence);
-    method @Deprecated public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived();
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived(boolean);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setPerson(androidx.core.app.Person);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setPersons(androidx.core.app.Person![]);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setRank(int);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setShortLabel(CharSequence);
-    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setSliceUri(android.net.Uri);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.core.content.pm.ShortcutInfoCompat.Builder setTransientExtras(android.os.Bundle);
-  }
-
-  @IntDef(flag=true, value={androidx.core.content.pm.ShortcutInfoCompat.SURFACE_LAUNCHER}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ShortcutInfoCompat.Surface {
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class ShortcutInfoCompatSaver<T> {
-    ctor public ShortcutInfoCompatSaver();
-    method @AnyThread public abstract T! addShortcuts(java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>!);
-    method @WorkerThread public java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>! getShortcuts() throws java.lang.Exception;
-    method @AnyThread public abstract T! removeAllShortcuts();
-    method @AnyThread public abstract T! removeShortcuts(java.util.List<java.lang.String!>!);
-  }
-
-  public class ShortcutManagerCompat {
-    method public static boolean addDynamicShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
-    method public static android.content.Intent createShortcutResultIntent(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat);
-    method public static void disableShortcuts(android.content.Context, java.util.List<java.lang.String!>, CharSequence?);
-    method public static void enableShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
-    method public static java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getDynamicShortcuts(android.content.Context);
-    method public static int getIconMaxHeight(android.content.Context);
-    method public static int getIconMaxWidth(android.content.Context);
-    method public static int getMaxShortcutCountPerActivity(android.content.Context);
-    method public static java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getShortcuts(android.content.Context, @androidx.core.content.pm.ShortcutManagerCompat.ShortcutMatchFlags int);
-    method public static boolean isRateLimitingActive(android.content.Context);
-    method public static boolean isRequestPinShortcutSupported(android.content.Context);
-    method public static boolean pushDynamicShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat);
-    method public static void removeAllDynamicShortcuts(android.content.Context);
-    method public static void removeDynamicShortcuts(android.content.Context, java.util.List<java.lang.String!>);
-    method public static void removeLongLivedShortcuts(android.content.Context, java.util.List<java.lang.String!>);
-    method public static void reportShortcutUsed(android.content.Context, String);
-    method public static boolean requestPinShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat, android.content.IntentSender?);
-    method public static boolean setDynamicShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
-    method public static boolean updateShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
-    field public static final String EXTRA_SHORTCUT_ID = "android.intent.extra.shortcut.ID";
-    field public static final int FLAG_MATCH_CACHED = 8; // 0x8
-    field public static final int FLAG_MATCH_DYNAMIC = 2; // 0x2
-    field public static final int FLAG_MATCH_MANIFEST = 1; // 0x1
-    field public static final int FLAG_MATCH_PINNED = 4; // 0x4
-  }
-
-  @IntDef(flag=true, value={androidx.core.content.pm.ShortcutManagerCompat.FLAG_MATCH_MANIFEST, androidx.core.content.pm.ShortcutManagerCompat.FLAG_MATCH_DYNAMIC, androidx.core.content.pm.ShortcutManagerCompat.FLAG_MATCH_PINNED, androidx.core.content.pm.ShortcutManagerCompat.FLAG_MATCH_CACHED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ShortcutManagerCompat.ShortcutMatchFlags {
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public class ShortcutXmlParser {
-    method @WorkerThread public static java.util.List<java.lang.String!> getShortcutIds(android.content.Context);
-    method @VisibleForTesting public static java.util.List<java.lang.String!> parseShortcutIds(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-  }
-
-}
-
-package androidx.core.content.res {
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class ColorStateListInflaterCompat {
-    method public static android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static android.content.res.ColorStateList createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static android.content.res.ColorStateList? inflate(android.content.res.Resources, @XmlRes int, android.content.res.Resources.Theme?);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class ComplexColorCompat {
-    method @ColorInt public int getColor();
-    method public android.graphics.Shader? getShader();
-    method public static androidx.core.content.res.ComplexColorCompat? inflate(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?);
-    method public boolean isGradient();
-    method public boolean isStateful();
-    method public boolean onStateChanged(int[]!);
-    method public void setColor(@ColorInt int);
-    method public boolean willDraw();
-  }
-
-  public final class ConfigurationHelper {
-    method public static int getDensityDpi(android.content.res.Resources);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class FontResourcesParserCompat {
-    method public static androidx.core.content.res.FontResourcesParserCompat.FamilyResourceEntry? parse(org.xmlpull.v1.XmlPullParser, android.content.res.Resources) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static java.util.List<java.util.List<byte[]!>!> readCerts(android.content.res.Resources, @ArrayRes int);
-    field public static final int FETCH_STRATEGY_ASYNC = 1; // 0x1
-    field public static final int FETCH_STRATEGY_BLOCKING = 0; // 0x0
-    field public static final int INFINITE_TIMEOUT_VALUE = -1; // 0xffffffff
-  }
-
-  public static interface FontResourcesParserCompat.FamilyResourceEntry {
-  }
-
-  @IntDef({androidx.core.content.res.FontResourcesParserCompat.FETCH_STRATEGY_BLOCKING, androidx.core.content.res.FontResourcesParserCompat.FETCH_STRATEGY_ASYNC}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface FontResourcesParserCompat.FetchStrategy {
-  }
-
-  public static final class FontResourcesParserCompat.FontFamilyFilesResourceEntry implements androidx.core.content.res.FontResourcesParserCompat.FamilyResourceEntry {
-    ctor public FontResourcesParserCompat.FontFamilyFilesResourceEntry(androidx.core.content.res.FontResourcesParserCompat.FontFileResourceEntry![]);
-    method public androidx.core.content.res.FontResourcesParserCompat.FontFileResourceEntry![] getEntries();
-  }
-
-  public static final class FontResourcesParserCompat.FontFileResourceEntry {
-    ctor public FontResourcesParserCompat.FontFileResourceEntry(String, int, boolean, String?, int, int);
-    method public String getFileName();
-    method public int getResourceId();
-    method public int getTtcIndex();
-    method public String? getVariationSettings();
-    method public int getWeight();
-    method public boolean isItalic();
-  }
-
-  public static final class FontResourcesParserCompat.ProviderResourceEntry implements androidx.core.content.res.FontResourcesParserCompat.FamilyResourceEntry {
-    ctor public FontResourcesParserCompat.ProviderResourceEntry(androidx.core.provider.FontRequest, @androidx.core.content.res.FontResourcesParserCompat.FetchStrategy int, int);
-    method @androidx.core.content.res.FontResourcesParserCompat.FetchStrategy public int getFetchStrategy();
-    method public androidx.core.provider.FontRequest getRequest();
-    method public int getTimeout();
-  }
-
-  public final class ResourcesCompat {
-    method public static void clearCachesForTheme(android.content.res.Resources.Theme);
-    method public static android.graphics.Typeface? getCachedFont(android.content.Context, @FontRes int) throws android.content.res.Resources.NotFoundException;
-    method @ColorInt public static int getColor(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
-    method public static android.content.res.ColorStateList? getColorStateList(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
-    method public static android.graphics.drawable.Drawable? getDrawable(android.content.res.Resources, @DrawableRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
-    method public static android.graphics.drawable.Drawable? getDrawableForDensity(android.content.res.Resources, @DrawableRes int, int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
-    method public static float getFloat(android.content.res.Resources, @DimenRes int);
-    method public static android.graphics.Typeface? getFont(android.content.Context, @FontRes int) throws android.content.res.Resources.NotFoundException;
-    method public static void getFont(android.content.Context, @FontRes int, androidx.core.content.res.ResourcesCompat.FontCallback, android.os.Handler?) throws android.content.res.Resources.NotFoundException;
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? getFont(android.content.Context, @FontRes int, android.util.TypedValue, int, androidx.core.content.res.ResourcesCompat.FontCallback?) throws android.content.res.Resources.NotFoundException;
-    field @AnyRes public static final int ID_NULL = 0; // 0x0
-  }
-
-  public abstract static class ResourcesCompat.FontCallback {
-    ctor public ResourcesCompat.FontCallback();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final void callbackFailAsync(@androidx.core.provider.FontsContractCompat.FontRequestCallback.FontRequestFailReason int, android.os.Handler?);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final void callbackSuccessAsync(android.graphics.Typeface, android.os.Handler?);
-    method public abstract void onFontRetrievalFailed(@androidx.core.provider.FontsContractCompat.FontRequestCallback.FontRequestFailReason int);
-    method public abstract void onFontRetrieved(android.graphics.Typeface);
-  }
-
-  public static final class ResourcesCompat.ThemeCompat {
-    method public static void rebase(android.content.res.Resources.Theme);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TypedArrayUtils {
-    method public static int getAttr(android.content.Context, int, int);
-    method public static boolean getBoolean(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int, boolean);
-    method public static android.graphics.drawable.Drawable? getDrawable(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int);
-    method public static int getInt(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int, int);
-    method public static boolean getNamedBoolean(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, @StyleableRes int, boolean);
-    method @ColorInt public static int getNamedColor(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, @StyleableRes int, @ColorInt int);
-    method public static android.content.res.ColorStateList? getNamedColorStateList(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme?, String, @StyleableRes int);
-    method public static androidx.core.content.res.ComplexColorCompat! getNamedComplexColor(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme?, String, @StyleableRes int, @ColorInt int);
-    method public static float getNamedFloat(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, @StyleableRes int, float);
-    method public static int getNamedInt(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, @StyleableRes int, int);
-    method @AnyRes public static int getNamedResourceId(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, @StyleableRes int, @AnyRes int);
-    method public static String? getNamedString(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, @StyleableRes int);
-    method @AnyRes public static int getResourceId(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int, @AnyRes int);
-    method public static String? getString(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int);
-    method public static CharSequence? getText(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int);
-    method public static CharSequence![]? getTextArray(android.content.res.TypedArray, @StyleableRes int, @StyleableRes int);
-    method public static boolean hasAttribute(org.xmlpull.v1.XmlPullParser, String);
-    method public static android.content.res.TypedArray obtainAttributes(android.content.res.Resources, android.content.res.Resources.Theme?, android.util.AttributeSet, int[]);
-    method public static android.util.TypedValue? peekNamedValue(android.content.res.TypedArray, org.xmlpull.v1.XmlPullParser, String, int);
-  }
-
-}
-
-package androidx.core.database {
-
-  public final class CursorWindowCompat {
-    method public static android.database.CursorWindow create(String?, long);
-  }
-
-  @Deprecated public final class DatabaseUtilsCompat {
-    method @Deprecated public static String![]! appendSelectionArgs(String![]!, String![]!);
-    method @Deprecated public static String! concatenateWhere(String!, String!);
-  }
-
-}
-
-package androidx.core.database.sqlite {
-
-  public final class SQLiteCursorCompat {
-    method public static void setFillWindowForwardOnly(android.database.sqlite.SQLiteCursor, boolean);
-  }
-
-}
-
-package androidx.core.graphics {
-
-  public final class BitmapCompat {
-    method public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap, int, int, android.graphics.Rect?, boolean);
-    method public static int getAllocationByteCount(android.graphics.Bitmap);
-    method public static boolean hasMipMap(android.graphics.Bitmap);
-    method public static void setHasMipMap(android.graphics.Bitmap, boolean);
-  }
-
-  public class BlendModeColorFilterCompat {
-    method public static android.graphics.ColorFilter? createBlendModeColorFilterCompat(int, androidx.core.graphics.BlendModeCompat);
-  }
-
-  public enum BlendModeCompat {
-    enum_constant public static final androidx.core.graphics.BlendModeCompat CLEAR;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR_BURN;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR_DODGE;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat DARKEN;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat DIFFERENCE;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat DST;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_ATOP;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_IN;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OUT;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OVER;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat EXCLUSION;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat HARD_LIGHT;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat HUE;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat LIGHTEN;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat LUMINOSITY;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat MODULATE;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat MULTIPLY;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat OVERLAY;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat PLUS;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat SATURATION;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat SCREEN;
-    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat SOFT_LIGHT;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_ATOP;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_IN;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OUT;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OVER;
-    enum_constant public static final androidx.core.graphics.BlendModeCompat XOR;
-  }
-
-  public final class ColorUtils {
-    method @ColorInt public static int HSLToColor(float[]);
-    method @ColorInt public static int LABToColor(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double);
-    method public static void LABToXYZ(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double, double[]);
-    method public static void RGBToHSL(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, float[]);
-    method public static void RGBToLAB(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, double[]);
-    method public static void RGBToXYZ(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, double[]);
-    method @ColorInt public static int XYZToColor(@FloatRange(from=0.0f, to=95.047) double, @FloatRange(from=0.0f, to=0x64) double, @FloatRange(from=0.0f, to=108.883) double);
-    method public static void XYZToLAB(@FloatRange(from=0.0f, to=95.047) double, @FloatRange(from=0.0f, to=0x64) double, @FloatRange(from=0.0f, to=108.883) double, double[]);
-    method @ColorInt public static int blendARGB(@ColorInt int, @ColorInt int, @FloatRange(from=0.0, to=1.0) float);
-    method public static void blendHSL(float[], float[], @FloatRange(from=0.0, to=1.0) float, float[]);
-    method public static void blendLAB(double[], double[], @FloatRange(from=0.0, to=1.0) double, double[]);
-    method public static double calculateContrast(@ColorInt int, @ColorInt int);
-    method @FloatRange(from=0.0, to=1.0) public static double calculateLuminance(@ColorInt int);
-    method public static int calculateMinimumAlpha(@ColorInt int, @ColorInt int, float);
-    method public static void colorToHSL(@ColorInt int, float[]);
-    method public static void colorToLAB(@ColorInt int, double[]);
-    method public static void colorToXYZ(@ColorInt int, double[]);
-    method public static int compositeColors(@ColorInt int, @ColorInt int);
-    method @RequiresApi(26) public static android.graphics.Color compositeColors(android.graphics.Color, android.graphics.Color);
-    method public static double distanceEuclidean(double[], double[]);
-    method @ColorInt public static int setAlphaComponent(@ColorInt int, @IntRange(from=0, to=255) int);
-  }
-
-  public final class Insets {
-    method public static androidx.core.graphics.Insets add(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
-    method public static androidx.core.graphics.Insets max(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
-    method public static androidx.core.graphics.Insets min(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
-    method public static androidx.core.graphics.Insets of(int, int, int, int);
-    method public static androidx.core.graphics.Insets of(android.graphics.Rect);
-    method public static androidx.core.graphics.Insets subtract(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
-    method @RequiresApi(api=29) public static androidx.core.graphics.Insets toCompatInsets(android.graphics.Insets);
-    method @RequiresApi(29) public android.graphics.Insets toPlatformInsets();
-    method @Deprecated @RequiresApi(api=29) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.graphics.Insets wrap(android.graphics.Insets);
-    field public static final androidx.core.graphics.Insets NONE;
-    field public final int bottom;
-    field public final int left;
-    field public final int right;
-    field public final int top;
-  }
-
-  public final class PaintCompat {
-    method public static boolean hasGlyph(android.graphics.Paint, String);
-    method public static boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat?);
-  }
-
-  public final class PathSegment {
-    ctor public PathSegment(android.graphics.PointF, float, android.graphics.PointF, float);
-    method public android.graphics.PointF getEnd();
-    method public float getEndFraction();
-    method public android.graphics.PointF getStart();
-    method public float getStartFraction();
-  }
-
-  public final class PathUtils {
-    method @RequiresApi(26) public static java.util.Collection<androidx.core.graphics.PathSegment!> flatten(android.graphics.Path);
-    method @RequiresApi(26) public static java.util.Collection<androidx.core.graphics.PathSegment!> flatten(android.graphics.Path, @FloatRange(from=0) float);
-  }
-
-  public class TypefaceCompat {
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @VisibleForTesting public static void clearCache();
-    method public static android.graphics.Typeface create(android.content.Context, android.graphics.Typeface?, int);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? createFromFontInfo(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo![], int);
-    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? createFromResourcesFamilyXml(android.content.Context, androidx.core.content.res.FontResourcesParserCompat.FamilyResourceEntry, android.content.res.Resources, int, int, androidx.core.content.res.ResourcesCompat.FontCallback?, android.os.Handler?, boolean);
-    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? createFromResourcesFontFile(android.content.Context, android.content.res.Resources, int, String!, int);
-    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface? findFromCache(android.content.res.Resources, int, int);
-  }
-
-  @RequiresApi(26) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TypefaceCompatApi26Impl {
-    ctor public TypefaceCompatApi26Impl();
-    method protected android.graphics.Typeface? createFromFamiliesWithDefault(Object!);
-    method public android.graphics.Typeface? createFromFontFamilyFilesResourceEntry(android.content.Context!, androidx.core.content.res.FontResourcesParserCompat.FontFamilyFilesResourceEntry!, android.content.res.Resources!, int);
-    method public android.graphics.Typeface? createFromFontInfo(android.content.Context!, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo![], int);
-    method public android.graphics.Typeface? createFromResourcesFontFile(android.content.Context!, android.content.res.Resources!, int, String!, int);
-    method protected java.lang.reflect.Method! obtainAbortCreationMethod(Class<?>!) throws java.lang.NoSuchMethodException;
-    method protected java.lang.reflect.Method! obtainAddFontFromAssetManagerMethod(Class<?>!) throws java.lang.NoSuchMethodException;
-    method protected java.lang.reflect.Method! obtainAddFontFromBufferMethod(Class<?>!) throws java.lang.NoSuchMethodException;
-    method protected java.lang.reflect.Method! obtainCreateFromFamiliesWithDefaultMethod(Class<?>!) throws java.lang.NoSuchMethodException;
-    method protected Class<?>! obtainFontFamily() throws java.lang.ClassNotFoundException;
-    method protected java.lang.reflect.Constructor<?>! obtainFontFamilyCtor(Class<?>!) throws java.lang.NoSuchMethodException;
-    method protected java.lang.reflect.Method! obtainFreezeMethod(Class<?>!) throws java.lang.NoSuchMethodException;
-    field protected final java.lang.reflect.Method! mAbortCreation;
-    field protected final java.lang.reflect.Method! mAddFontFromAssetManager;
-    field protected final java.lang.reflect.Method! mAddFontFromBuffer;
-    field protected final java.lang.reflect.Method! mCreateFromFamiliesWithDefault;
-    field protected final Class<?>! mFontFamily;
-    field protected final java.lang.reflect.Constructor<?>! mFontFamilyCtor;
-    field protected final java.lang.reflect.Method! mFreeze;
-  }
-
-  @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TypefaceCompatApi28Impl extends androidx.core.graphics.TypefaceCompatApi26Impl {
-    ctor public TypefaceCompatApi28Impl();
-  }
-
-  @RequiresApi(29) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public class TypefaceCompatApi29Impl {
-    ctor public TypefaceCompatApi29Impl();
-    method public android.graphics.Typeface? createFromFontFamilyFilesResourceEntry(android.content.Context!, androidx.core.content.res.FontResourcesParserCompat.FontFamilyFilesResourceEntry!, android.content.res.Resources!, int);
-    method public android.graphics.Typeface? createFromFontInfo(android.content.Context!, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo![], int);
-    method protected android.graphics.Typeface! createFromInputStream(android.content.Context!, java.io.InputStream!);
-    method public android.graphics.Typeface? createFromResourcesFontFile(android.content.Context!, android.content.res.Resources!, int, String!, int);
-    method protected androidx.core.provider.FontsContractCompat.FontInfo! findBestInfo(androidx.core.provider.FontsContractCompat.FontInfo![]!, int);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TypefaceCompatUtil {
-    method public static void closeQuietly(java.io.Closeable?);
-    method @RequiresApi(19) public static java.nio.ByteBuffer? copyToDirectBuffer(android.content.Context, android.content.res.Resources, int);
-    method public static boolean copyToFile(java.io.File, java.io.InputStream);
-    method public static boolean copyToFile(java.io.File, android.content.res.Resources, int);
-    method public static java.io.File? getTempFile(android.content.Context);
-    method @RequiresApi(19) public static java.nio.ByteBuffer? mmap(android.content.Context, android.os.CancellationSignal?, android.net.Uri);
-  }
-
-}
-
-package androidx.core.graphics.drawable {
-
-  public final class DrawableCompat {
-    method public static void applyTheme(android.graphics.drawable.Drawable, android.content.res.Resources.Theme);
-    method public static boolean canApplyTheme(android.graphics.drawable.Drawable);
-    method public static void clearColorFilter(android.graphics.drawable.Drawable);
-    method public static int getAlpha(android.graphics.drawable.Drawable);
-    method public static android.graphics.ColorFilter? getColorFilter(android.graphics.drawable.Drawable);
-    method public static int getLayoutDirection(android.graphics.drawable.Drawable);
-    method public static void inflate(android.graphics.drawable.Drawable, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public static boolean isAutoMirrored(android.graphics.drawable.Drawable);
-    method @Deprecated public static void jumpToCurrentState(android.graphics.drawable.Drawable);
-    method public static void setAutoMirrored(android.graphics.drawable.Drawable, boolean);
-    method public static void setHotspot(android.graphics.drawable.Drawable, float, float);
-    method public static void setHotspotBounds(android.graphics.drawable.Drawable, int, int, int, int);
-    method public static boolean setLayoutDirection(android.graphics.drawable.Drawable, int);
-    method public static void setTint(android.graphics.drawable.Drawable, @ColorInt int);
-    method public static void setTintList(android.graphics.drawable.Drawable, android.content.res.ColorStateList?);
-    method public static void setTintMode(android.graphics.drawable.Drawable, android.graphics.PorterDuff.Mode);
-    method public static <T extends android.graphics.drawable.Drawable> T! unwrap(android.graphics.drawable.Drawable);
-    method public static android.graphics.drawable.Drawable wrap(android.graphics.drawable.Drawable);
-  }
-
-  @androidx.versionedparcelable.VersionedParcelize(allowSerialization=true, ignoreParcelables=true, isCustom=true, jetifyAs="android.support.v4.graphics.drawable.IconCompat") public class IconCompat extends androidx.versionedparcelable.CustomVersionedParcelable {
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void addToShortcutIntent(android.content.Intent, android.graphics.drawable.Drawable?, android.content.Context);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void checkResource(android.content.Context);
-    method public static androidx.core.graphics.drawable.IconCompat? createFromBundle(android.os.Bundle);
-    method @RequiresApi(23) public static androidx.core.graphics.drawable.IconCompat? createFromIcon(android.content.Context, android.graphics.drawable.Icon);
-    method @RequiresApi(23) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.graphics.drawable.IconCompat? createFromIcon(android.graphics.drawable.Icon);
-    method @RequiresApi(23) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.graphics.drawable.IconCompat? createFromIconOrNullIfZeroResId(android.graphics.drawable.Icon);
-    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmap(android.graphics.Bitmap);
-    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmapContentUri(String);
-    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmapContentUri(android.net.Uri);
-    method public static androidx.core.graphics.drawable.IconCompat createWithBitmap(android.graphics.Bitmap);
-    method public static androidx.core.graphics.drawable.IconCompat createWithContentUri(String);
-    method public static androidx.core.graphics.drawable.IconCompat createWithContentUri(android.net.Uri);
-    method public static androidx.core.graphics.drawable.IconCompat createWithData(byte[], int, int);
-    method public static androidx.core.graphics.drawable.IconCompat createWithResource(android.content.Context, @DrawableRes int);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.graphics.drawable.IconCompat createWithResource(android.content.res.Resources?, String, @DrawableRes int);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.graphics.Bitmap? getBitmap();
-    method @DrawableRes public int getResId();
-    method public String getResPackage();
-    method public int getType();
-    method public android.net.Uri getUri();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public java.io.InputStream? getUriInputStream(android.content.Context);
-    method public android.graphics.drawable.Drawable? loadDrawable(android.content.Context);
-    method public androidx.core.graphics.drawable.IconCompat setTint(@ColorInt int);
-    method public androidx.core.graphics.drawable.IconCompat setTintList(android.content.res.ColorStateList?);
-    method public androidx.core.graphics.drawable.IconCompat setTintMode(android.graphics.PorterDuff.Mode?);
-    method public android.os.Bundle toBundle();
-    method @Deprecated @RequiresApi(23) public android.graphics.drawable.Icon toIcon();
-    method @RequiresApi(23) public android.graphics.drawable.Icon toIcon(android.content.Context?);
-    field public static final int TYPE_ADAPTIVE_BITMAP = 5; // 0x5
-    field public static final int TYPE_BITMAP = 1; // 0x1
-    field public static final int TYPE_DATA = 3; // 0x3
-    field public static final int TYPE_RESOURCE = 2; // 0x2
-    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
-    field public static final int TYPE_URI = 4; // 0x4
-    field public static final int TYPE_URI_ADAPTIVE_BITMAP = 6; // 0x6
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @androidx.versionedparcelable.ParcelField(value=1, defaultValue="androidx.core.graphics.drawable.IconCompat.TYPE_UNKNOWN") public int mType;
-  }
-
-  public abstract class RoundedBitmapDrawable extends android.graphics.drawable.Drawable {
-    method public void draw(android.graphics.Canvas);
-    method public final android.graphics.Bitmap? getBitmap();
-    method public float getCornerRadius();
-    method public int getGravity();
-    method public int getOpacity();
-    method public final android.graphics.Paint getPaint();
-    method public boolean hasAntiAlias();
-    method public boolean hasMipMap();
-    method public boolean isCircular();
-    method public void setAlpha(int);
-    method public void setAntiAlias(boolean);
-    method public void setCircular(boolean);
-    method public void setColorFilter(android.graphics.ColorFilter!);
-    method public void setCornerRadius(float);
-    method public void setDither(boolean);
-    method public void setGravity(int);
-    method public void setMipMap(boolean);
-    method public void setTargetDensity(android.graphics.Canvas);
-    method public void setTargetDensity(android.util.DisplayMetrics);
-    method public void setTargetDensity(int);
-  }
-
-  public final class RoundedBitmapDrawableFactory {
-    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, android.graphics.Bitmap?);
-    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, String);
-    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, java.io.InputStream);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface TintAwareDrawable {
-    method public void setTint(@ColorInt int);
-    method public void setTintList(android.content.res.ColorStateList!);
-    method public void setTintMode(android.graphics.PorterDuff.Mode!);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface WrappedDrawable {
-    method public android.graphics.drawable.Drawable! getWrappedDrawable();
-    method public void setWrappedDrawable(android.graphics.drawable.Drawable!);
-  }
-
-}
-
-package androidx.core.hardware.display {
-
-  public final class DisplayManagerCompat {
-    method public android.view.Display? getDisplay(int);
-    method public android.view.Display![] getDisplays();
-    method public android.view.Display![] getDisplays(String?);
-    method public static androidx.core.hardware.display.DisplayManagerCompat getInstance(android.content.Context);
-    field public static final String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
-  }
-
-}
-
-package androidx.core.hardware.fingerprint {
-
-  @Deprecated public class FingerprintManagerCompat {
-    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public void authenticate(androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject?, int, androidx.core.os.CancellationSignal?, androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationCallback, android.os.Handler?);
-    method @Deprecated public static androidx.core.hardware.fingerprint.FingerprintManagerCompat from(android.content.Context);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean hasEnrolledFingerprints();
-    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean isHardwareDetected();
-  }
-
-  @Deprecated public abstract static class FingerprintManagerCompat.AuthenticationCallback {
-    ctor @Deprecated public FingerprintManagerCompat.AuthenticationCallback();
-    method @Deprecated public void onAuthenticationError(int, CharSequence!);
-    method @Deprecated public void onAuthenticationFailed();
-    method @Deprecated public void onAuthenticationHelp(int, CharSequence!);
-    method @Deprecated public void onAuthenticationSucceeded(androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationResult!);
-  }
-
-  @Deprecated public static final class FingerprintManagerCompat.AuthenticationResult {
-    ctor @Deprecated public FingerprintManagerCompat.AuthenticationResult(androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject!);
-    method @Deprecated public androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject! getCryptoObject();
-  }
-
-  @Deprecated public static class FingerprintManagerCompat.CryptoObject {
-    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(java.security.Signature);
-    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(javax.crypto.Cipher);
-    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(javax.crypto.Mac);
-    method @Deprecated public javax.crypto.Cipher? getCipher();
-    method @Deprecated public javax.crypto.Mac? getMac();
-    method @Deprecated public java.security.Signature? getSignature();
-  }
-
-}
-
-package androidx.core.internal.view {
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface SupportMenu extends android.view.Menu {
-    method public void setGroupDividerEnabled(boolean);
-    field public static final int CATEGORY_MASK = -65536; // 0xffff0000
-    field public static final int CATEGORY_SHIFT = 16; // 0x10
-    field public static final int FLAG_KEEP_OPEN_ON_SUBMENU_OPENED = 4; // 0x4
-    field public static final int SUPPORTED_MODIFIERS_MASK = 69647; // 0x1100f
-    field public static final int USER_MASK = 65535; // 0xffff
-    field public static final int USER_SHIFT = 0; // 0x0
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface SupportMenuItem extends android.view.MenuItem {
-    method public int getAlphabeticModifiers();
-    method public CharSequence? getContentDescription();
-    method public android.content.res.ColorStateList? getIconTintList();
-    method public android.graphics.PorterDuff.Mode? getIconTintMode();
-    method public int getNumericModifiers();
-    method public androidx.core.view.ActionProvider? getSupportActionProvider();
-    method public CharSequence? getTooltipText();
-    method public boolean requiresActionButton();
-    method public boolean requiresOverflow();
-    method public android.view.MenuItem setAlphabeticShortcut(char, int);
-    method public androidx.core.internal.view.SupportMenuItem setContentDescription(CharSequence?);
-    method public android.view.MenuItem setIconTintList(android.content.res.ColorStateList?);
-    method public android.view.MenuItem setIconTintMode(android.graphics.PorterDuff.Mode?);
-    method public android.view.MenuItem setNumericShortcut(char, int);
-    method public android.view.MenuItem setShortcut(char, char, int, int);
-    method public androidx.core.internal.view.SupportMenuItem setSupportActionProvider(androidx.core.view.ActionProvider?);
-    method public androidx.core.internal.view.SupportMenuItem setTooltipText(CharSequence?);
-    field public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
-    field public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; // 0x8
-    field public static final int SHOW_AS_ACTION_IF_ROOM = 1; // 0x1
-    field public static final int SHOW_AS_ACTION_NEVER = 0; // 0x0
-    field public static final int SHOW_AS_ACTION_WITH_TEXT = 4; // 0x4
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface SupportSubMenu extends androidx.core.internal.view.SupportMenu android.view.SubMenu {
-  }
-
-}
-
-package androidx.core.location {
-
-  public abstract class GnssStatusCompat {
-    method @FloatRange(from=0, to=360) public abstract float getAzimuthDegrees(@IntRange(from=0) int);
-    method @FloatRange(from=0, to=63) public abstract float getBasebandCn0DbHz(@IntRange(from=0) int);
-    method @FloatRange(from=0) public abstract float getCarrierFrequencyHz(@IntRange(from=0) int);
-    method @FloatRange(from=0, to=63) public abstract float getCn0DbHz(@IntRange(from=0) int);
-    method public abstract int getConstellationType(@IntRange(from=0) int);
-    method @FloatRange(from=0xffffffa6, to=90) public abstract float getElevationDegrees(@IntRange(from=0) int);
-    method @IntRange(from=0) public abstract int getSatelliteCount();
-    method @IntRange(from=1, to=200) public abstract int getSvid(@IntRange(from=0) int);
-    method public abstract boolean hasAlmanacData(@IntRange(from=0) int);
-    method public abstract boolean hasBasebandCn0DbHz(@IntRange(from=0) int);
-    method public abstract boolean hasCarrierFrequencyHz(@IntRange(from=0) int);
-    method public abstract boolean hasEphemerisData(@IntRange(from=0) int);
-    method public abstract boolean usedInFix(@IntRange(from=0) int);
-    method @RequiresApi(android.os.Build.VERSION_CODES.N) public static androidx.core.location.GnssStatusCompat wrap(android.location.GnssStatus);
-    method public static androidx.core.location.GnssStatusCompat wrap(android.location.GpsStatus);
-    field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
-    field public static final int CONSTELLATION_GALILEO = 6; // 0x6
-    field public static final int CONSTELLATION_GLONASS = 3; // 0x3
-    field public static final int CONSTELLATION_GPS = 1; // 0x1
-    field public static final int CONSTELLATION_IRNSS = 7; // 0x7
-    field public static final int CONSTELLATION_QZSS = 4; // 0x4
-    field public static final int CONSTELLATION_SBAS = 2; // 0x2
-    field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
-  }
-
-  public abstract static class GnssStatusCompat.Callback {
-    ctor public GnssStatusCompat.Callback();
-    method public void onFirstFix(@IntRange(from=0) int);
-    method public void onSatelliteStatusChanged(androidx.core.location.GnssStatusCompat);
-    method public void onStarted();
-    method public void onStopped();
-  }
-
-  public final class LocationCompat {
-    method public static float getBearingAccuracyDegrees(android.location.Location);
-    method public static long getElapsedRealtimeMillis(android.location.Location);
-    method public static long getElapsedRealtimeNanos(android.location.Location);
-    method public static float getSpeedAccuracyMetersPerSecond(android.location.Location);
-    method public static float getVerticalAccuracyMeters(android.location.Location);
-    method public static boolean hasBearingAccuracy(android.location.Location);
-    method public static boolean hasSpeedAccuracy(android.location.Location);
-    method public static boolean hasVerticalAccuracy(android.location.Location);
-    method public static boolean isMock(android.location.Location);
-    method public static void setBearingAccuracyDegrees(android.location.Location, float);
-    method public static void setMock(android.location.Location, boolean);
-    method public static void setSpeedAccuracyMetersPerSecond(android.location.Location, float);
-    method public static void setVerticalAccuracyMeters(android.location.Location, float);
-    field public static final String EXTRA_BEARING_ACCURACY = "bearingAccuracy";
-    field public static final String EXTRA_IS_MOCK = "mockLocation";
-    field public static final String EXTRA_SPEED_ACCURACY = "speedAccuracy";
-    field public static final String EXTRA_VERTICAL_ACCURACY = "verticalAccuracy";
-  }
-
-  public interface LocationListenerCompat extends android.location.LocationListener {
-    method public default void onStatusChanged(String, int, android.os.Bundle?);
-  }
-
-  public final class LocationManagerCompat {
-    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void getCurrentLocation(android.location.LocationManager, String, androidx.core.os.CancellationSignal?, java.util.concurrent.Executor, androidx.core.util.Consumer<android.location.Location!>);
-    method public static String? getGnssHardwareModelName(android.location.LocationManager);
-    method public static int getGnssYearOfHardware(android.location.LocationManager);
-    method public static boolean hasProvider(android.location.LocationManager, String);
-    method public static boolean isLocationEnabled(android.location.LocationManager);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssStatusCallback(android.location.LocationManager, androidx.core.location.GnssStatusCompat.Callback, android.os.Handler);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssStatusCallback(android.location.LocationManager, java.util.concurrent.Executor, androidx.core.location.GnssStatusCompat.Callback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void removeUpdates(android.location.LocationManager, androidx.core.location.LocationListenerCompat);
-    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void requestLocationUpdates(android.location.LocationManager, String, androidx.core.location.LocationRequestCompat, java.util.concurrent.Executor, androidx.core.location.LocationListenerCompat);
-    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void requestLocationUpdates(android.location.LocationManager, String, androidx.core.location.LocationRequestCompat, androidx.core.location.LocationListenerCompat, android.os.Looper);
-    method public static void unregisterGnssStatusCallback(android.location.LocationManager, androidx.core.location.GnssStatusCompat.Callback);
-  }
-
-  public final class LocationRequestCompat {
-    method @IntRange(from=1) public long getDurationMillis();
-    method @IntRange(from=0) public long getIntervalMillis();
-    method @IntRange(from=0) public long getMaxUpdateDelayMillis();
-    method @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getMaxUpdates();
-    method @FloatRange(from=0, to=java.lang.Float.MAX_VALUE) public float getMinUpdateDistanceMeters();
-    method @IntRange(from=0) public long getMinUpdateIntervalMillis();
-    method public int getQuality();
-    method @RequiresApi(31) public android.location.LocationRequest toLocationRequest();
-    method @RequiresApi(19) public android.location.LocationRequest? toLocationRequest(String);
-    field public static final long PASSIVE_INTERVAL = 9223372036854775807L; // 0x7fffffffffffffffL
-    field public static final int QUALITY_BALANCED_POWER_ACCURACY = 102; // 0x66
-    field public static final int QUALITY_HIGH_ACCURACY = 100; // 0x64
-    field public static final int QUALITY_LOW_POWER = 104; // 0x68
-  }
-
-  public static final class LocationRequestCompat.Builder {
-    ctor public LocationRequestCompat.Builder(long);
-    ctor public LocationRequestCompat.Builder(androidx.core.location.LocationRequestCompat);
-    method public androidx.core.location.LocationRequestCompat build();
-    method public androidx.core.location.LocationRequestCompat.Builder clearMinUpdateIntervalMillis();
-    method public androidx.core.location.LocationRequestCompat.Builder setDurationMillis(@IntRange(from=1) long);
-    method public androidx.core.location.LocationRequestCompat.Builder setIntervalMillis(@IntRange(from=0) long);
-    method public androidx.core.location.LocationRequestCompat.Builder setMaxUpdateDelayMillis(@IntRange(from=0) long);
-    method public androidx.core.location.LocationRequestCompat.Builder setMaxUpdates(@IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int);
-    method public androidx.core.location.LocationRequestCompat.Builder setMinUpdateDistanceMeters(@FloatRange(from=0, to=java.lang.Float.MAX_VALUE) float);
-    method public androidx.core.location.LocationRequestCompat.Builder setMinUpdateIntervalMillis(@IntRange(from=0) long);
-    method public androidx.core.location.LocationRequestCompat.Builder setQuality(int);
-  }
-
-}
-
-package androidx.core.math {
-
-  public class MathUtils {
-    method public static int addExact(int, int);
-    method public static long addExact(long, long);
-    method public static float clamp(float, float, float);
-    method public static double clamp(double, double, double);
-    method public static int clamp(int, int, int);
-    method public static long clamp(long, long, long);
-    method public static int decrementExact(int);
-    method public static long decrementExact(long);
-    method public static int incrementExact(int);
-    method public static long incrementExact(long);
-    method public static int multiplyExact(int, int);
-    method public static long multiplyExact(long, long);
-    method public static int negateExact(int);
-    method public static long negateExact(long);
-    method public static int subtractExact(int, int);
-    method public static long subtractExact(long, long);
-    method public static int toIntExact(long);
-  }
-
-}
-
-package androidx.core.net {
-
-  public final class ConnectivityManagerCompat {
-    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static android.net.NetworkInfo? getNetworkInfoFromBroadcast(android.net.ConnectivityManager, android.content.Intent);
-    method @androidx.core.net.ConnectivityManagerCompat.RestrictBackgroundStatus public static int getRestrictBackgroundStatus(android.net.ConnectivityManager);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static boolean isActiveNetworkMetered(android.net.ConnectivityManager);
-    field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
-    field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
-    field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
-  }
-
-  @IntDef({androidx.core.net.ConnectivityManagerCompat.RESTRICT_BACKGROUND_STATUS_DISABLED, androidx.core.net.ConnectivityManagerCompat.RESTRICT_BACKGROUND_STATUS_WHITELISTED, androidx.core.net.ConnectivityManagerCompat.RESTRICT_BACKGROUND_STATUS_ENABLED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ConnectivityManagerCompat.RestrictBackgroundStatus {
-  }
-
-  public final class MailTo {
-    method public String? getBcc();
-    method public String? getBody();
-    method public String? getCc();
-    method public java.util.Map<java.lang.String!,java.lang.String!>? getHeaders();
-    method public String? getSubject();
-    method public String? getTo();
-    method public static boolean isMailTo(String?);
-    method public static boolean isMailTo(android.net.Uri?);
-    method public static androidx.core.net.MailTo parse(String) throws androidx.core.net.ParseException;
-    method public static androidx.core.net.MailTo parse(android.net.Uri) throws androidx.core.net.ParseException;
-    field public static final String MAILTO_SCHEME = "mailto:";
-  }
-
-  public class ParseException extends java.lang.RuntimeException {
-    field public final String response;
-  }
-
-  public final class TrafficStatsCompat {
-    method @Deprecated public static void clearThreadStatsTag();
-    method @Deprecated public static int getThreadStatsTag();
-    method @Deprecated public static void incrementOperationCount(int);
-    method @Deprecated public static void incrementOperationCount(int, int);
-    method @Deprecated public static void setThreadStatsTag(int);
-    method public static void tagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
-    method @Deprecated public static void tagSocket(java.net.Socket!) throws java.net.SocketException;
-    method public static void untagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
-    method @Deprecated public static void untagSocket(java.net.Socket!) throws java.net.SocketException;
-  }
-
-  public final class UriCompat {
-    method public static String toSafeString(android.net.Uri);
-  }
-
-}
-
-package androidx.core.os {
-
-  public class BuildCompat {
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.N) public static boolean isAtLeastN();
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.N_MR1) public static boolean isAtLeastNMR1();
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.O) public static boolean isAtLeastO();
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.O_MR1) public static boolean isAtLeastOMR1();
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.P) public static boolean isAtLeastP();
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.Q) public static boolean isAtLeastQ();
-    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.R) public static boolean isAtLeastR();
-    method @Deprecated @ChecksSdkIntAtLeast(api=31, codename="S") public static boolean isAtLeastS();
-  }
-
-  public final class CancellationSignal {
-    ctor public CancellationSignal();
-    method public void cancel();
-    method public Object? getCancellationSignalObject();
-    method public boolean isCanceled();
-    method public void setOnCancelListener(androidx.core.os.CancellationSignal.OnCancelListener?);
-    method public void throwIfCanceled();
-  }
-
-  public static interface CancellationSignal.OnCancelListener {
-    method public void onCancel();
-  }
-
-  public final class ConfigurationCompat {
-    method public static androidx.core.os.LocaleListCompat getLocales(android.content.res.Configuration);
-  }
-
-  public final class EnvironmentCompat {
-    method public static String getStorageState(java.io.File);
-    field public static final String MEDIA_UNKNOWN = "unknown";
-  }
-
-  public final class ExecutorCompat {
-    method public static java.util.concurrent.Executor create(android.os.Handler);
-  }
-
-  public final class HandlerCompat {
-    method public static android.os.Handler createAsync(android.os.Looper);
-    method public static android.os.Handler createAsync(android.os.Looper, android.os.Handler.Callback);
-    method @RequiresApi(16) public static boolean hasCallbacks(android.os.Handler, Runnable);
-    method public static boolean postDelayed(android.os.Handler, Runnable, Object?, long);
-  }
-
-  public final class LocaleListCompat {
-    method public static androidx.core.os.LocaleListCompat create(java.util.Locale!...);
-    method public static androidx.core.os.LocaleListCompat forLanguageTags(String?);
-    method public java.util.Locale? get(int);
-    method @Size(min=1) public static androidx.core.os.LocaleListCompat getAdjustedDefault();
-    method @Size(min=1) public static androidx.core.os.LocaleListCompat getDefault();
-    method public static androidx.core.os.LocaleListCompat getEmptyLocaleList();
-    method public java.util.Locale? getFirstMatch(String![]);
-    method @IntRange(from=0xffffffff) public int indexOf(java.util.Locale?);
-    method public boolean isEmpty();
-    method @IntRange(from=0) public int size();
-    method public String toLanguageTags();
-    method public Object? unwrap();
-    method @Deprecated @RequiresApi(24) public static androidx.core.os.LocaleListCompat! wrap(Object!);
-    method @RequiresApi(24) public static androidx.core.os.LocaleListCompat wrap(android.os.LocaleList);
-  }
-
-  public final class MessageCompat {
-    method public static boolean isAsynchronous(android.os.Message);
-    method public static void setAsynchronous(android.os.Message, boolean);
-  }
-
-  public class OperationCanceledException extends java.lang.RuntimeException {
-    ctor public OperationCanceledException();
-    ctor public OperationCanceledException(String?);
-  }
-
-  public final class ParcelCompat {
-    method public static boolean readBoolean(android.os.Parcel);
-    method public static void writeBoolean(android.os.Parcel, boolean);
-  }
-
-  @Deprecated public final class ParcelableCompat {
-    method @Deprecated public static <T> android.os.Parcelable.Creator<T!>! newCreator(androidx.core.os.ParcelableCompatCreatorCallbacks<T!>!);
-  }
-
-  @Deprecated public interface ParcelableCompatCreatorCallbacks<T> {
-    method @Deprecated public T! createFromParcel(android.os.Parcel!, ClassLoader!);
-    method @Deprecated public T![]! newArray(int);
-  }
-
-  public final class ProcessCompat {
-    method public static boolean isApplicationUid(int);
-  }
-
-  @Deprecated public final class TraceCompat {
-    method @Deprecated public static void beginAsyncSection(String, int);
-    method @Deprecated public static void beginSection(String);
-    method @Deprecated public static void endAsyncSection(String, int);
-    method @Deprecated public static void endSection();
-    method @Deprecated public static boolean isEnabled();
-    method @Deprecated public static void setCounter(String, int);
-  }
-
-  @RequiresApi(17) public class UserHandleCompat {
-    method public static android.os.UserHandle getUserHandleForUid(int);
-  }
-
-  public class UserManagerCompat {
-    method public static boolean isUserUnlocked(android.content.Context);
-  }
-
-}
-
-package androidx.core.provider {
-
-  public final class DocumentsContractCompat {
-    method public static android.net.Uri? buildChildDocumentsUri(String, String?);
-    method public static android.net.Uri? buildChildDocumentsUriUsingTree(android.net.Uri, String);
-    method public static android.net.Uri? buildDocumentUri(String, String);
-    method public static android.net.Uri? buildDocumentUriUsingTree(android.net.Uri, String);
-    method public static android.net.Uri? buildTreeDocumentUri(String, String);
-    method public static android.net.Uri? createDocument(android.content.ContentResolver, android.net.Uri, String, String) throws java.io.FileNotFoundException;
-    method public static String? getDocumentId(android.net.Uri);
-    method public static String? getTreeDocumentId(android.net.Uri);
-    method public static boolean isDocumentUri(android.content.Context, android.net.Uri?);
-    method public static boolean isTreeUri(android.net.Uri);
-    method public static boolean removeDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
-    method public static android.net.Uri? renameDocument(android.content.ContentResolver, android.net.Uri, String) throws java.io.FileNotFoundException;
-  }
-
-  public static final class DocumentsContractCompat.DocumentCompat {
-    field public static final int FLAG_VIRTUAL_DOCUMENT = 512; // 0x200
-  }
-
-  public final class FontRequest {
-    ctor public FontRequest(String, String, String, java.util.List<java.util.List<byte[]!>!>);
-    ctor public FontRequest(String, String, String, @ArrayRes int);
-    method public java.util.List<java.util.List<byte[]!>!>? getCertificates();
-    method @ArrayRes public int getCertificatesArrayResId();
-    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public String! getIdentifier();
-    method public String getProviderAuthority();
-    method public String getProviderPackage();
-    method public String getQuery();
-  }
-
-  public class FontsContractCompat {
-    method public static android.graphics.Typeface? buildTypeface(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo![]);
-    method public static androidx.core.provider.FontsContractCompat.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException;
-    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.graphics.Typeface! getFontSync(android.content.Context!, androidx.core.provider.FontRequest!, androidx.core.content.res.ResourcesCompat.FontCallback?, android.os.Handler?, boolean, int, int);
-    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @VisibleForTesting public static android.content.pm.ProviderInfo? getProvider(android.content.pm.PackageManager, androidx.core.provider.FontRequest, android.content.res.Resources?) throws android.content.pm.PackageManager.NameNotFoundException;
-    method @Deprecated @RequiresApi(19) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static java.util.Map<android.net.Uri!,java.nio.ByteBuffer!>! prepareFontData(android.content.Context!, androidx.core.provider.FontsContractCompat.FontInfo![]!, android.os.CancellationSignal!);
-    method public static void requestFont(android.content.Context, androidx.core.provider.FontRequest, androidx.core.provider.FontsContractCompat.FontRequestCallback, android.os.Handler);
-    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void resetCache();
-    field @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final String PARCEL_FONT_RESULTS = "font_results";
-  }
-
-  public static final class FontsContractCompat.Columns implements android.provider.BaseColumns {
-    ctor public FontsContractCompat.Columns();
-    field public static final String FILE_ID = "file_id";
-    field public static final String ITALIC = "font_italic";
-    field public static final String RESULT_CODE = "result_code";
-    field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
-    field public static final int RESULT_CODE_FONT_UNAVAILABLE = 2; // 0x2
-    field public static final int RESULT_CODE_MALFORMED_QUERY = 3; // 0x3
-    field public static final int RESULT_CODE_OK = 0; // 0x0
-    field public static final String TTC_INDEX = "font_ttc_index";
-    field public static final String VARIATION_SETTINGS = "font_variation_settings";
-    field public static final String WEIGHT = "font_weight";
-  }
-
-  public static class FontsContractCompat.FontFamilyResult {
-    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public FontsContractCompat.FontFamilyResult(int, androidx.core.provider.FontsContractCompat.FontInfo![]?);
-    method public androidx.core.provider.FontsContractCompat.FontInfo![]! getFonts();
-    method public int getStatusCode();
-    field public static final int STATUS_OK = 0; // 0x0
-    field public static final int STATUS_UNEXPECTED_DATA_PROVIDED = 2; // 0x2
-    field public static final int STATUS_WRONG_CERTIFICATES = 1; // 0x1
-  }
-
-  public static class FontsContractCompat.FontInfo {
-    ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public FontsContractCompat.FontInfo(android.net.Uri, @IntRange(from=0) int, @IntRange(from=1, to=1000) int, boolean, int);
-    method public int getResultCode();
-    method @IntRange(from=0) public int getTtcIndex();
-    method public android.net.Uri getUri();
-    method @IntRange(from=1, to=1000) public int getWeight();
-    method public boolean isItalic();
-  }
-
-  public static class FontsContractCompat.FontRequestCallback {
-    ctor public FontsContractCompat.FontRequestCallback();
-    method public void onTypefaceRequestFailed(@androidx.core.provider.FontsContractCompat.FontRequestCallback.FontRequestFailReason int);
-    method public void onTypefaceRetrieved(android.graphics.Typeface!);
-    field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
-    field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
-    field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
-    field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
-    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
-    field public static final int FAIL_REASON_SECURITY_VIOLATION = -4; // 0xfffffffc
-    field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
-    field @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final int RESULT_OK = 0; // 0x0
-  }
-
-  @IntDef({androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND, androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR, androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND, androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_FONT_UNAVAILABLE, androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_MALFORMED_QUERY, androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_WRONG_CERTIFICATES, androidx.core.provider.FontsContractCompat.FontRequestCallback.FAIL_REASON_SECURITY_VIOLATION, androidx.core.provider.FontsContractCompat.FontRequestCallback.RESULT_OK}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface FontsContractCompat.FontRequestCallback.FontRequestFailReason {
-  }
-
-  @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class SelfDestructiveThread {
-    ctor @Deprecated public SelfDestructiveThread(String!, int, int);
-    method @Deprecated @VisibleForTesting public int getGeneration();
-    method @Deprecated @VisibleForTesting public boolean isRunning();
-    method @Deprecated public <T> void postAndReply(java.util.concurrent.Callable<T!>!, androidx.core.provider.SelfDestructiveThread.ReplyCallback<T!>!);
-    method @Deprecated public <T> T! postAndWait(java.util.concurrent.Callable<T!>!, int) throws java.lang.InterruptedException;
-  }
-
-  @Deprecated public static interface SelfDestructiveThread.ReplyCallback<T> {
-    method @Deprecated public void onReply(T!);
-  }
-
-}
-
-package androidx.core.telephony {
-
-  @RequiresApi(22) public class SubscriptionManagerCompat {
-    method public static int getSlotIndex(int);
-  }
-
-  public class TelephonyManagerCompat {
-    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static String? getImei(android.telephony.TelephonyManager);
-    method public static int getSubscriptionId(android.telephony.TelephonyManager);
-  }
-
-}
-
-package androidx.core.telephony.mbms {
-
-  public final class MbmsHelper {
-    method public static CharSequence? getBestNameForService(android.content.Context, android.telephony.mbms.ServiceInfo);
-  }
-
-}
-
-package androidx.core.text {
-
-  public final class BidiFormatter {
-    method public static androidx.core.text.BidiFormatter! getInstance();
-    method public static androidx.core.text.BidiFormatter! getInstance(boolean);
-    method public static androidx.core.text.BidiFormatter! getInstance(java.util.Locale!);
-    method public boolean getStereoReset();
-    method public boolean isRtl(String!);
-    method public boolean isRtl(CharSequence!);
-    method public boolean isRtlContext();
-    method public String! unicodeWrap(String!, androidx.core.text.TextDirectionHeuristicCompat!, boolean);
-    method public CharSequence! unicodeWrap(CharSequence!, androidx.core.text.TextDirectionHeuristicCompat!, boolean);
-    method public String! unicodeWrap(String!, androidx.core.text.TextDirectionHeuristicCompat!);
-    method public CharSequence! unicodeWrap(CharSequence!, androidx.core.text.TextDirectionHeuristicCompat!);
-    method public String! unicodeWrap(String!, boolean);
-    method public CharSequence! unicodeWrap(CharSequence!, boolean);
-    method public String! unicodeWrap(String!);
-    method public CharSequence! unicodeWrap(CharSequence!);
-  }
-
-  public static final class BidiFormatter.Builder {
-    ctor public BidiFormatter.Builder();
-    ctor public BidiFormatter.Builder(boolean);
-    ctor public BidiFormatter.Builder(java.util.Locale!);
-    method public androidx.core.text.BidiFormatter! build();
-    method public androidx.core.text.BidiFormatter.Builder! setTextDirectionHeuristic(androidx.core.text.TextDirectionHeuristicCompat!);
-    method public androidx.core.text.BidiFormatter.Builder! stereoReset(boolean);
-  }
-
-  public final class HtmlCompat {
-    method public static android.text.Spanned fromHtml(String, int);
-    method public static android.text.Spanned fromHtml(String, int, android.text.Html.ImageGetter?, android.text.Html.TagHandler?);
-    method public static String toHtml(android.text.Spanned, int);
-    field public static final int FROM_HTML_MODE_COMPACT = 63; // 0x3f
-    field public static final int FROM_HTML_MODE_LEGACY = 0; // 0x0
-    field public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256; // 0x100
-    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32; // 0x20
-    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16; // 0x10
-    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2; // 0x2
-    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8; // 0x8
-    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4; // 0x4
-    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1; // 0x1
-    field public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0; // 0x0
-    field public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1; // 0x1
-  }
-
-  public final class ICUCompat {
-    method public static String? maximizeAndGetScript(java.util.Locale);
-  }
-
-  public class PrecomputedTextCompat implements android.text.Spannable {
-    method public char charAt(int);
-    method public static androidx.core.text.PrecomputedTextCompat! create(CharSequence, androidx.core.text.PrecomputedTextCompat.Params);
-    method @IntRange(from=0) public int getParagraphCount();
-    method @IntRange(from=0) public int getParagraphEnd(@IntRange(from=0) int);
-    method @IntRange(from=0) public int getParagraphStart(@IntRange(from=0) int);
-    method public androidx.core.text.PrecomputedTextCompat.Params getParams();
-    method @RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.text.PrecomputedText? getPrecomputedText();
-    method public int getSpanEnd(Object!);
-    method public int getSpanFlags(Object!);
-    method public int getSpanStart(Object!);
-    method public <T> T![]! getSpans(int, int, Class<T!>!);
-    method @UiThread public static java.util.concurrent.Future<androidx.core.text.PrecomputedTextCompat!>! getTextFuture(CharSequence, androidx.core.text.PrecomputedTextCompat.Params, java.util.concurrent.Executor?);
-    method public int length();
-    method public int nextSpanTransition(int, int, Class!);
-    method public void removeSpan(Object!);
-    method public void setSpan(Object!, int, int, int);
-    method public CharSequence! subSequence(int, int);
-  }
-
-  public static final class PrecomputedTextCompat.Params {
-    ctor @RequiresApi(28) public PrecomputedTextCompat.Params(android.text.PrecomputedText.Params);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean equalsWithoutTextDirection(androidx.core.text.PrecomputedTextCompat.Params);
-    method @RequiresApi(23) public int getBreakStrategy();
-    method @RequiresApi(23) public int getHyphenationFrequency();
-    method @RequiresApi(18) public android.text.TextDirectionHeuristic? getTextDirection();
-    method public android.text.TextPaint getTextPaint();
-  }
-
-  public static class PrecomputedTextCompat.Params.Builder {
-    ctor public PrecomputedTextCompat.Params.Builder(android.text.TextPaint);
-    method public androidx.core.text.PrecomputedTextCompat.Params build();
-    method @RequiresApi(23) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setBreakStrategy(int);
-    method @RequiresApi(23) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setHyphenationFrequency(int);
-    method @RequiresApi(18) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setTextDirection(android.text.TextDirectionHeuristic);
-  }
-
-  public interface TextDirectionHeuristicCompat {
-    method public boolean isRtl(char[]!, int, int);
-    method public boolean isRtl(CharSequence!, int, int);
-  }
-
-  public final class TextDirectionHeuristicsCompat {
-    field public static final androidx.core.text.TextDirectionHeuristicCompat! ANYRTL_LTR;
-    field public static final androidx.core.text.TextDirectionHeuristicCompat! FIRSTSTRONG_LTR;
-    field public static final androidx.core.text.TextDirectionHeuristicCompat! FIRSTSTRONG_RTL;
-    field public static final androidx.core.text.TextDirectionHeuristicCompat! LOCALE;
-    field public static final androidx.core.text.TextDirectionHeuristicCompat! LTR;
-    field public static final androidx.core.text.TextDirectionHeuristicCompat! RTL;
-  }
-
-  public final class TextUtilsCompat {
-    method public static int getLayoutDirectionFromLocale(java.util.Locale?);
-    method public static String htmlEncode(String);
-  }
-
-}
-
-package androidx.core.text.util {
-
-  public final class LinkifyCompat {
-    method public static boolean addLinks(android.text.Spannable, @androidx.core.text.util.LinkifyCompat.LinkifyMask int);
-    method public static boolean addLinks(android.widget.TextView, @androidx.core.text.util.LinkifyCompat.LinkifyMask int);
-    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?);
-    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
-    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?, String![]?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
-    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?);
-    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
-    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?, String![]?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
-  }
-
-  @IntDef(flag=true, value={android.text.util.Linkify.WEB_URLS, android.text.util.Linkify.EMAIL_ADDRESSES, android.text.util.Linkify.PHONE_NUMBERS, android.text.util.Linkify.MAP_ADDRESSES, android.text.util.Linkify.ALL}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface LinkifyCompat.LinkifyMask {
-  }
-
-}
-
-package androidx.core.util {
-
-  public class AtomicFile {
-    ctor public AtomicFile(java.io.File);
-    method public void delete();
-    method public void failWrite(java.io.FileOutputStream?);
-    method public void finishWrite(java.io.FileOutputStream?);
-    method public java.io.File getBaseFile();
-    method public java.io.FileInputStream openRead() throws java.io.FileNotFoundException;
-    method public byte[] readFully() throws java.io.IOException;
-    method public java.io.FileOutputStream startWrite() throws java.io.IOException;
-  }
-
-  public interface Consumer<T> {
-    method public void accept(T!);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class DebugUtils {
-    method public static void buildShortClassTag(Object!, StringBuilder!);
-  }
-
-  @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class LogWriter extends java.io.Writer {
-    ctor @Deprecated public LogWriter(String!);
-    method @Deprecated public void close();
-    method @Deprecated public void flush();
-    method @Deprecated public void write(char[]!, int, int);
-  }
-
-  public class ObjectsCompat {
-    method public static boolean equals(Object?, Object?);
-    method public static int hash(java.lang.Object!...);
-    method public static int hashCode(Object?);
-    method public static <T> T requireNonNull(T?);
-    method public static <T> T requireNonNull(T?, String);
-    method public static String? toString(Object?, String?);
-  }
-
-  public class Pair<F, S> {
-    ctor public Pair(F!, S!);
-    method public static <A, B> androidx.core.util.Pair<A!,B!> create(A!, B!);
-    field public final F! first;
-    field public final S! second;
-  }
-
-  public final class PatternsCompat {
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final java.util.regex.Pattern AUTOLINK_EMAIL_ADDRESS;
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final java.util.regex.Pattern AUTOLINK_WEB_URL;
-    field public static final java.util.regex.Pattern DOMAIN_NAME;
-    field public static final java.util.regex.Pattern EMAIL_ADDRESS;
-    field public static final java.util.regex.Pattern IP_ADDRESS;
-    field public static final java.util.regex.Pattern WEB_URL;
-  }
-
-  public final class Pools {
-  }
-
-  public static interface Pools.Pool<T> {
-    method public T? acquire();
-    method public boolean release(T);
-  }
-
-  public static class Pools.SimplePool<T> implements androidx.core.util.Pools.Pool<T> {
-    ctor public Pools.SimplePool(int);
-    method public T! acquire();
-    method public boolean release(T);
-  }
-
-  public static class Pools.SynchronizedPool<T> extends androidx.core.util.Pools.SimplePool<T> {
-    ctor public Pools.SynchronizedPool(int);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class Preconditions {
-    method public static void checkArgument(boolean);
-    method public static void checkArgument(boolean, Object);
-    method public static void checkArgument(boolean, String, java.lang.Object!...);
-    method public static float checkArgumentFinite(float, String);
-    method public static int checkArgumentInRange(int, int, int, String);
-    method public static long checkArgumentInRange(long, long, long, String);
-    method public static float checkArgumentInRange(float, float, float, String);
-    method public static double checkArgumentInRange(double, double, double, String);
-    method @IntRange(from=0) public static int checkArgumentNonnegative(int, String?);
-    method @IntRange(from=0) public static int checkArgumentNonnegative(int);
-    method public static int checkFlagsArgument(int, int);
-    method public static <T> T checkNotNull(T?);
-    method public static <T> T checkNotNull(T?, Object);
-    method public static void checkState(boolean, String?);
-    method public static void checkState(boolean);
-    method public static <T extends java.lang.CharSequence> T checkStringNotEmpty(T?);
-    method public static <T extends java.lang.CharSequence> T checkStringNotEmpty(T?, Object);
-    method public static <T extends java.lang.CharSequence> T checkStringNotEmpty(T?, String, java.lang.Object!...);
-  }
-
-  public interface Predicate<T> {
-    method public boolean test(T!);
-  }
-
-  public final class SizeFCompat {
-    ctor public SizeFCompat(float, float);
-    method public float getHeight();
-    method public float getWidth();
-    method @RequiresApi(21) public android.util.SizeF toSizeF();
-    method @RequiresApi(21) public static androidx.core.util.SizeFCompat toSizeFCompat(android.util.SizeF);
-  }
-
-  public interface Supplier<T> {
-    method public T! get();
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class TimeUtils {
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void formatDuration(long, StringBuilder!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void formatDuration(long, java.io.PrintWriter!, int);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void formatDuration(long, java.io.PrintWriter!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void formatDuration(long, long, java.io.PrintWriter!);
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final int HUNDRED_DAY_FIELD_LEN = 19; // 0x13
-  }
-
-}
-
-package androidx.core.view {
-
-  public class AccessibilityDelegateCompat {
-    ctor public AccessibilityDelegateCompat();
-    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public AccessibilityDelegateCompat(android.view.View.AccessibilityDelegate);
-    method public boolean dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
-    method public androidx.core.view.accessibility.AccessibilityNodeProviderCompat? getAccessibilityNodeProvider(android.view.View);
-    method public void onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
-    method public void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
-    method public void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
-    method public boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
-    method public boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
-    method public void sendAccessibilityEvent(android.view.View, int);
-    method public void sendAccessibilityEventUnchecked(android.view.View, android.view.accessibility.AccessibilityEvent);
-  }
-
-  public abstract class ActionProvider {
-    ctor public ActionProvider(android.content.Context);
-    method public android.content.Context getContext();
-    method public boolean hasSubMenu();
-    method public boolean isVisible();
-    method public abstract android.view.View onCreateActionView();
-    method public android.view.View onCreateActionView(android.view.MenuItem);
-    method public boolean onPerformDefaultAction();
-    method public void onPrepareSubMenu(android.view.SubMenu);
-    method public boolean overridesItemVisibility();
-    method public void refreshVisibility();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void reset();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setSubUiVisibilityListener(androidx.core.view.ActionProvider.SubUiVisibilityListener?);
-    method public void setVisibilityListener(androidx.core.view.ActionProvider.VisibilityListener?);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void subUiVisibilityChanged(boolean);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static interface ActionProvider.SubUiVisibilityListener {
-    method public void onSubUiVisibilityChanged(boolean);
-  }
-
-  public static interface ActionProvider.VisibilityListener {
-    method public void onActionProviderVisibilityChanged(boolean);
-  }
-
-  public final class ContentInfoCompat {
-    method public android.content.ClipData getClip();
-    method public android.os.Bundle? getExtras();
-    method @androidx.core.view.ContentInfoCompat.Flags public int getFlags();
-    method public android.net.Uri? getLinkUri();
-    method @androidx.core.view.ContentInfoCompat.Source public int getSource();
-    method public android.util.Pair<androidx.core.view.ContentInfoCompat!,androidx.core.view.ContentInfoCompat!> partition(androidx.core.util.Predicate<android.content.ClipData.Item!>);
-    method @RequiresApi(31) public static android.util.Pair<android.view.ContentInfo!,android.view.ContentInfo!> partition(android.view.ContentInfo, java.util.function.Predicate<android.content.ClipData.Item!>);
-    method @RequiresApi(31) public android.view.ContentInfo toContentInfo();
-    method @RequiresApi(31) public static androidx.core.view.ContentInfoCompat toContentInfoCompat(android.view.ContentInfo);
-    field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1
-    field public static final int SOURCE_APP = 0; // 0x0
-    field public static final int SOURCE_AUTOFILL = 4; // 0x4
-    field public static final int SOURCE_CLIPBOARD = 1; // 0x1
-    field public static final int SOURCE_DRAG_AND_DROP = 3; // 0x3
-    field public static final int SOURCE_INPUT_METHOD = 2; // 0x2
-    field public static final int SOURCE_PROCESS_TEXT = 5; // 0x5
-  }
-
-  public static final class ContentInfoCompat.Builder {
-    ctor public ContentInfoCompat.Builder(androidx.core.view.ContentInfoCompat);
-    ctor public ContentInfoCompat.Builder(android.content.ClipData, @androidx.core.view.ContentInfoCompat.Source int);
-    method public androidx.core.view.ContentInfoCompat build();
-    method public androidx.core.view.ContentInfoCompat.Builder setClip(android.content.ClipData);
-    method public androidx.core.view.ContentInfoCompat.Builder setExtras(android.os.Bundle?);
-    method public androidx.core.view.ContentInfoCompat.Builder setFlags(@androidx.core.view.ContentInfoCompat.Flags int);
-    method public androidx.core.view.ContentInfoCompat.Builder setLinkUri(android.net.Uri?);
-    method public androidx.core.view.ContentInfoCompat.Builder setSource(@androidx.core.view.ContentInfoCompat.Source int);
-  }
-
-  @IntDef(flag=true, value={androidx.core.view.ContentInfoCompat.FLAG_CONVERT_TO_PLAIN_TEXT}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ContentInfoCompat.Flags {
-  }
-
-  @IntDef({androidx.core.view.ContentInfoCompat.SOURCE_APP, androidx.core.view.ContentInfoCompat.SOURCE_CLIPBOARD, androidx.core.view.ContentInfoCompat.SOURCE_INPUT_METHOD, androidx.core.view.ContentInfoCompat.SOURCE_DRAG_AND_DROP, androidx.core.view.ContentInfoCompat.SOURCE_AUTOFILL, androidx.core.view.ContentInfoCompat.SOURCE_PROCESS_TEXT}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ContentInfoCompat.Source {
-  }
-
-  public final class DisplayCompat {
-    method public static androidx.core.view.DisplayCompat.ModeCompat getMode(android.content.Context, android.view.Display);
-    method public static androidx.core.view.DisplayCompat.ModeCompat![] getSupportedModes(android.content.Context, android.view.Display);
-  }
-
-  public static final class DisplayCompat.ModeCompat {
-    method public int getPhysicalHeight();
-    method public int getPhysicalWidth();
-    method @Deprecated public boolean isNative();
-    method @RequiresApi(android.os.Build.VERSION_CODES.M) public android.view.Display.Mode? toMode();
-  }
-
-  public final class DisplayCutoutCompat {
-    ctor public DisplayCutoutCompat(android.graphics.Rect?, java.util.List<android.graphics.Rect!>?);
-    ctor public DisplayCutoutCompat(androidx.core.graphics.Insets, android.graphics.Rect?, android.graphics.Rect?, android.graphics.Rect?, android.graphics.Rect?, androidx.core.graphics.Insets);
-    method public java.util.List<android.graphics.Rect!> getBoundingRects();
-    method public int getSafeInsetBottom();
-    method public int getSafeInsetLeft();
-    method public int getSafeInsetRight();
-    method public int getSafeInsetTop();
-    method public androidx.core.graphics.Insets getWaterfallInsets();
-  }
-
-  public final class DragAndDropPermissionsCompat {
-    method public void release();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static androidx.core.view.DragAndDropPermissionsCompat? request(android.app.Activity, android.view.DragEvent);
-  }
-
-  public class DragStartHelper {
-    ctor public DragStartHelper(android.view.View, androidx.core.view.DragStartHelper.OnDragStartListener);
-    method public void attach();
-    method public void detach();
-    method public void getTouchPosition(android.graphics.Point);
-    method public boolean onLongClick(android.view.View);
-    method public boolean onTouch(android.view.View, android.view.MotionEvent);
-  }
-
-  public static interface DragStartHelper.OnDragStartListener {
-    method public boolean onDragStart(android.view.View, androidx.core.view.DragStartHelper);
-  }
-
-  public final class GestureDetectorCompat {
-    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener);
-    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler?);
-    method public boolean isLongpressEnabled();
-    method public boolean onTouchEvent(android.view.MotionEvent);
-    method public void setIsLongpressEnabled(boolean);
-    method public void setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener?);
-  }
-
-  public final class GravityCompat {
-    method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect, int);
-    method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect, int);
-    method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect, int);
-    method public static int getAbsoluteGravity(int, int);
-    field public static final int END = 8388613; // 0x800005
-    field public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = 8388615; // 0x800007
-    field public static final int RELATIVE_LAYOUT_DIRECTION = 8388608; // 0x800000
-    field public static final int START = 8388611; // 0x800003
-  }
-
-  public final class InputDeviceCompat {
-    field public static final int SOURCE_ANY = -256; // 0xffffff00
-    field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
-    field public static final int SOURCE_CLASS_JOYSTICK = 16; // 0x10
-    field public static final int SOURCE_CLASS_MASK = 255; // 0xff
-    field public static final int SOURCE_CLASS_NONE = 0; // 0x0
-    field public static final int SOURCE_CLASS_POINTER = 2; // 0x2
-    field public static final int SOURCE_CLASS_POSITION = 8; // 0x8
-    field public static final int SOURCE_CLASS_TRACKBALL = 4; // 0x4
-    field public static final int SOURCE_DPAD = 513; // 0x201
-    field public static final int SOURCE_GAMEPAD = 1025; // 0x401
-    field public static final int SOURCE_HDMI = 33554433; // 0x2000001
-    field public static final int SOURCE_JOYSTICK = 16777232; // 0x1000010
-    field public static final int SOURCE_KEYBOARD = 257; // 0x101
-    field public static final int SOURCE_MOUSE = 8194; // 0x2002
-    field public static final int SOURCE_ROTARY_ENCODER = 4194304; // 0x400000
-    field public static final int SOURCE_STYLUS = 16386; // 0x4002
-    field public static final int SOURCE_TOUCHPAD = 1048584; // 0x100008
-    field public static final int SOURCE_TOUCHSCREEN = 4098; // 0x1002
-    field public static final int SOURCE_TOUCH_NAVIGATION = 2097152; // 0x200000
-    field public static final int SOURCE_TRACKBALL = 65540; // 0x10004
-    field public static final int SOURCE_UNKNOWN = 0; // 0x0
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class KeyEventDispatcher {
-    method public static boolean dispatchBeforeHierarchy(android.view.View, android.view.KeyEvent);
-    method public static boolean dispatchKeyEvent(androidx.core.view.KeyEventDispatcher.Component, android.view.View?, android.view.Window.Callback?, android.view.KeyEvent);
-  }
-
-  public static interface KeyEventDispatcher.Component {
-    method public boolean superDispatchKeyEvent(android.view.KeyEvent);
-  }
-
-  public final class LayoutInflaterCompat {
-    method @Deprecated public static androidx.core.view.LayoutInflaterFactory! getFactory(android.view.LayoutInflater!);
-    method @Deprecated public static void setFactory(android.view.LayoutInflater, androidx.core.view.LayoutInflaterFactory);
-    method public static void setFactory2(android.view.LayoutInflater, android.view.LayoutInflater.Factory2);
-  }
-
-  @Deprecated public interface LayoutInflaterFactory {
-    method @Deprecated public android.view.View! onCreateView(android.view.View!, String!, android.content.Context!, android.util.AttributeSet!);
-  }
-
-  public final class MarginLayoutParamsCompat {
-    method public static int getLayoutDirection(android.view.ViewGroup.MarginLayoutParams);
-    method public static int getMarginEnd(android.view.ViewGroup.MarginLayoutParams);
-    method public static int getMarginStart(android.view.ViewGroup.MarginLayoutParams);
-    method public static boolean isMarginRelative(android.view.ViewGroup.MarginLayoutParams);
-    method public static void resolveLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
-    method public static void setLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
-    method public static void setMarginEnd(android.view.ViewGroup.MarginLayoutParams, int);
-    method public static void setMarginStart(android.view.ViewGroup.MarginLayoutParams, int);
-  }
-
-  public final class MenuCompat {
-    method public static void setGroupDividerEnabled(android.view.Menu, boolean);
-    method @Deprecated public static void setShowAsAction(android.view.MenuItem!, int);
-  }
-
-  public interface MenuHost {
-    method public void addMenuProvider(androidx.core.view.MenuProvider);
-    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner);
-    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State);
-    method public void invalidateMenu();
-    method public void removeMenuProvider(androidx.core.view.MenuProvider);
-  }
-
-  public class MenuHostHelper {
-    ctor public MenuHostHelper(Runnable);
-    method public void addMenuProvider(androidx.core.view.MenuProvider);
-    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner);
-    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State);
-    method public void onCreateMenu(android.view.Menu, android.view.MenuInflater);
-    method public void onMenuClosed(android.view.Menu);
-    method public boolean onMenuItemSelected(android.view.MenuItem);
-    method public void onPrepareMenu(android.view.Menu);
-    method public void removeMenuProvider(androidx.core.view.MenuProvider);
-  }
-
-  public final class MenuItemCompat {
-    method @Deprecated public static boolean collapseActionView(android.view.MenuItem!);
-    method @Deprecated public static boolean expandActionView(android.view.MenuItem!);
-    method public static androidx.core.view.ActionProvider? getActionProvider(android.view.MenuItem);
-    method @Deprecated public static android.view.View! getActionView(android.view.MenuItem!);
-    method public static int getAlphabeticModifiers(android.view.MenuItem);
-    method public static CharSequence? getContentDescription(android.view.MenuItem);
-    method public static android.content.res.ColorStateList? getIconTintList(android.view.MenuItem);
-    method public static android.graphics.PorterDuff.Mode? getIconTintMode(android.view.MenuItem);
-    method public static int getNumericModifiers(android.view.MenuItem);
-    method public static CharSequence? getTooltipText(android.view.MenuItem);
-    method @Deprecated public static boolean isActionViewExpanded(android.view.MenuItem!);
-    method public static android.view.MenuItem? setActionProvider(android.view.MenuItem, androidx.core.view.ActionProvider?);
-    method @Deprecated public static android.view.MenuItem! setActionView(android.view.MenuItem!, android.view.View!);
-    method @Deprecated public static android.view.MenuItem! setActionView(android.view.MenuItem!, int);
-    method public static void setAlphabeticShortcut(android.view.MenuItem, char, int);
-    method public static void setContentDescription(android.view.MenuItem, CharSequence?);
-    method public static void setIconTintList(android.view.MenuItem, android.content.res.ColorStateList?);
-    method public static void setIconTintMode(android.view.MenuItem, android.graphics.PorterDuff.Mode?);
-    method public static void setNumericShortcut(android.view.MenuItem, char, int);
-    method @Deprecated public static android.view.MenuItem! setOnActionExpandListener(android.view.MenuItem!, androidx.core.view.MenuItemCompat.OnActionExpandListener!);
-    method public static void setShortcut(android.view.MenuItem, char, char, int, int);
-    method @Deprecated public static void setShowAsAction(android.view.MenuItem!, int);
-    method public static void setTooltipText(android.view.MenuItem, CharSequence?);
-    field @Deprecated public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
-    field @Deprecated public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; // 0x8
-    field @Deprecated public static final int SHOW_AS_ACTION_IF_ROOM = 1; // 0x1
-    field @Deprecated public static final int SHOW_AS_ACTION_NEVER = 0; // 0x0
-    field @Deprecated public static final int SHOW_AS_ACTION_WITH_TEXT = 4; // 0x4
-  }
-
-  @Deprecated public static interface MenuItemCompat.OnActionExpandListener {
-    method @Deprecated public boolean onMenuItemActionCollapse(android.view.MenuItem!);
-    method @Deprecated public boolean onMenuItemActionExpand(android.view.MenuItem!);
-  }
-
-  public interface MenuProvider {
-    method public void onCreateMenu(android.view.Menu, android.view.MenuInflater);
-    method public default void onMenuClosed(android.view.Menu);
-    method public boolean onMenuItemSelected(android.view.MenuItem);
-    method public default void onPrepareMenu(android.view.Menu);
-  }
-
-  public final class MotionEventCompat {
-    method @Deprecated public static int findPointerIndex(android.view.MotionEvent!, int);
-    method @Deprecated public static int getActionIndex(android.view.MotionEvent!);
-    method @Deprecated public static int getActionMasked(android.view.MotionEvent!);
-    method @Deprecated public static float getAxisValue(android.view.MotionEvent!, int);
-    method @Deprecated public static float getAxisValue(android.view.MotionEvent!, int, int);
-    method @Deprecated public static int getButtonState(android.view.MotionEvent!);
-    method @Deprecated public static int getPointerCount(android.view.MotionEvent!);
-    method @Deprecated public static int getPointerId(android.view.MotionEvent!, int);
-    method @Deprecated public static int getSource(android.view.MotionEvent!);
-    method @Deprecated public static float getX(android.view.MotionEvent!, int);
-    method @Deprecated public static float getY(android.view.MotionEvent!, int);
-    method public static boolean isFromSource(android.view.MotionEvent, int);
-    field @Deprecated public static final int ACTION_HOVER_ENTER = 9; // 0x9
-    field @Deprecated public static final int ACTION_HOVER_EXIT = 10; // 0xa
-    field @Deprecated public static final int ACTION_HOVER_MOVE = 7; // 0x7
-    field @Deprecated public static final int ACTION_MASK = 255; // 0xff
-    field @Deprecated public static final int ACTION_POINTER_DOWN = 5; // 0x5
-    field @Deprecated public static final int ACTION_POINTER_INDEX_MASK = 65280; // 0xff00
-    field @Deprecated public static final int ACTION_POINTER_INDEX_SHIFT = 8; // 0x8
-    field @Deprecated public static final int ACTION_POINTER_UP = 6; // 0x6
-    field @Deprecated public static final int ACTION_SCROLL = 8; // 0x8
-    field @Deprecated public static final int AXIS_BRAKE = 23; // 0x17
-    field @Deprecated public static final int AXIS_DISTANCE = 24; // 0x18
-    field @Deprecated public static final int AXIS_GAS = 22; // 0x16
-    field @Deprecated public static final int AXIS_GENERIC_1 = 32; // 0x20
-    field @Deprecated public static final int AXIS_GENERIC_10 = 41; // 0x29
-    field @Deprecated public static final int AXIS_GENERIC_11 = 42; // 0x2a
-    field @Deprecated public static final int AXIS_GENERIC_12 = 43; // 0x2b
-    field @Deprecated public static final int AXIS_GENERIC_13 = 44; // 0x2c
-    field @Deprecated public static final int AXIS_GENERIC_14 = 45; // 0x2d
-    field @Deprecated public static final int AXIS_GENERIC_15 = 46; // 0x2e
-    field @Deprecated public static final int AXIS_GENERIC_16 = 47; // 0x2f
-    field @Deprecated public static final int AXIS_GENERIC_2 = 33; // 0x21
-    field @Deprecated public static final int AXIS_GENERIC_3 = 34; // 0x22
-    field @Deprecated public static final int AXIS_GENERIC_4 = 35; // 0x23
-    field @Deprecated public static final int AXIS_GENERIC_5 = 36; // 0x24
-    field @Deprecated public static final int AXIS_GENERIC_6 = 37; // 0x25
-    field @Deprecated public static final int AXIS_GENERIC_7 = 38; // 0x26
-    field @Deprecated public static final int AXIS_GENERIC_8 = 39; // 0x27
-    field @Deprecated public static final int AXIS_GENERIC_9 = 40; // 0x28
-    field @Deprecated public static final int AXIS_HAT_X = 15; // 0xf
-    field @Deprecated public static final int AXIS_HAT_Y = 16; // 0x10
-    field @Deprecated public static final int AXIS_HSCROLL = 10; // 0xa
-    field @Deprecated public static final int AXIS_LTRIGGER = 17; // 0x11
-    field @Deprecated public static final int AXIS_ORIENTATION = 8; // 0x8
-    field @Deprecated public static final int AXIS_PRESSURE = 2; // 0x2
-    field public static final int AXIS_RELATIVE_X = 27; // 0x1b
-    field public static final int AXIS_RELATIVE_Y = 28; // 0x1c
-    field @Deprecated public static final int AXIS_RTRIGGER = 18; // 0x12
-    field @Deprecated public static final int AXIS_RUDDER = 20; // 0x14
-    field @Deprecated public static final int AXIS_RX = 12; // 0xc
-    field @Deprecated public static final int AXIS_RY = 13; // 0xd
-    field @Deprecated public static final int AXIS_RZ = 14; // 0xe
-    field public static final int AXIS_SCROLL = 26; // 0x1a
-    field @Deprecated public static final int AXIS_SIZE = 3; // 0x3
-    field @Deprecated public static final int AXIS_THROTTLE = 19; // 0x13
-    field @Deprecated public static final int AXIS_TILT = 25; // 0x19
-    field @Deprecated public static final int AXIS_TOOL_MAJOR = 6; // 0x6
-    field @Deprecated public static final int AXIS_TOOL_MINOR = 7; // 0x7
-    field @Deprecated public static final int AXIS_TOUCH_MAJOR = 4; // 0x4
-    field @Deprecated public static final int AXIS_TOUCH_MINOR = 5; // 0x5
-    field @Deprecated public static final int AXIS_VSCROLL = 9; // 0x9
-    field @Deprecated public static final int AXIS_WHEEL = 21; // 0x15
-    field @Deprecated public static final int AXIS_X = 0; // 0x0
-    field @Deprecated public static final int AXIS_Y = 1; // 0x1
-    field @Deprecated public static final int AXIS_Z = 11; // 0xb
-    field @Deprecated public static final int BUTTON_PRIMARY = 1; // 0x1
-  }
-
-  public interface NestedScrollingChild {
-    method public boolean dispatchNestedFling(float, float, boolean);
-    method public boolean dispatchNestedPreFling(float, float);
-    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?);
-    method public boolean dispatchNestedScroll(int, int, int, int, int[]?);
-    method public boolean hasNestedScrollingParent();
-    method public boolean isNestedScrollingEnabled();
-    method public void setNestedScrollingEnabled(boolean);
-    method public boolean startNestedScroll(@androidx.core.view.ViewCompat.ScrollAxis int);
-    method public void stopNestedScroll();
-  }
-
-  public interface NestedScrollingChild2 extends androidx.core.view.NestedScrollingChild {
-    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public boolean hasNestedScrollingParent(@androidx.core.view.ViewCompat.NestedScrollType int);
-    method public boolean startNestedScroll(@androidx.core.view.ViewCompat.ScrollAxis int, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public void stopNestedScroll(@androidx.core.view.ViewCompat.NestedScrollType int);
-  }
-
-  public interface NestedScrollingChild3 extends androidx.core.view.NestedScrollingChild2 {
-    method public void dispatchNestedScroll(int, int, int, int, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int, int[]);
-  }
-
-  public class NestedScrollingChildHelper {
-    ctor public NestedScrollingChildHelper(android.view.View);
-    method public boolean dispatchNestedFling(float, float, boolean);
-    method public boolean dispatchNestedPreFling(float, float);
-    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?);
-    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public boolean dispatchNestedScroll(int, int, int, int, int[]?);
-    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public void dispatchNestedScroll(int, int, int, int, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int, int[]?);
-    method public boolean hasNestedScrollingParent();
-    method public boolean hasNestedScrollingParent(@androidx.core.view.ViewCompat.NestedScrollType int);
-    method public boolean isNestedScrollingEnabled();
-    method public void onDetachedFromWindow();
-    method public void onStopNestedScroll(android.view.View);
-    method public void setNestedScrollingEnabled(boolean);
-    method public boolean startNestedScroll(@androidx.core.view.ViewCompat.ScrollAxis int);
-    method public boolean startNestedScroll(@androidx.core.view.ViewCompat.ScrollAxis int, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public void stopNestedScroll();
-    method public void stopNestedScroll(@androidx.core.view.ViewCompat.NestedScrollType int);
-  }
-
-  public interface NestedScrollingParent {
-    method @androidx.core.view.ViewCompat.ScrollAxis public int getNestedScrollAxes();
-    method public boolean onNestedFling(android.view.View, float, float, boolean);
-    method public boolean onNestedPreFling(android.view.View, float, float);
-    method public void onNestedPreScroll(android.view.View, int, int, int[]);
-    method public void onNestedScroll(android.view.View, int, int, int, int);
-    method public void onNestedScrollAccepted(android.view.View, android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int);
-    method public boolean onStartNestedScroll(android.view.View, android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int);
-    method public void onStopNestedScroll(android.view.View);
-  }
-
-  public interface NestedScrollingParent2 extends androidx.core.view.NestedScrollingParent {
-    method public void onNestedPreScroll(android.view.View, int, int, int[], @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public void onNestedScroll(android.view.View, int, int, int, int, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public void onNestedScrollAccepted(android.view.View, android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public boolean onStartNestedScroll(android.view.View, android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public void onStopNestedScroll(android.view.View, @androidx.core.view.ViewCompat.NestedScrollType int);
-  }
-
-  public interface NestedScrollingParent3 extends androidx.core.view.NestedScrollingParent2 {
-    method public void onNestedScroll(android.view.View, int, int, int, int, @androidx.core.view.ViewCompat.NestedScrollType int, int[]);
-  }
-
-  public class NestedScrollingParentHelper {
-    ctor public NestedScrollingParentHelper(android.view.ViewGroup);
-    method @androidx.core.view.ViewCompat.ScrollAxis public int getNestedScrollAxes();
-    method public void onNestedScrollAccepted(android.view.View, android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int);
-    method public void onNestedScrollAccepted(android.view.View, android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public void onStopNestedScroll(android.view.View);
-    method public void onStopNestedScroll(android.view.View, @androidx.core.view.ViewCompat.NestedScrollType int);
-  }
-
-  public interface OnApplyWindowInsetsListener {
-    method public androidx.core.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
-  }
-
-  public interface OnReceiveContentListener {
-    method public androidx.core.view.ContentInfoCompat? onReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
-  }
-
-  public interface OnReceiveContentViewBehavior {
-    method public androidx.core.view.ContentInfoCompat? onReceiveContent(androidx.core.view.ContentInfoCompat);
-  }
-
-  public final class OneShotPreDrawListener implements android.view.View.OnAttachStateChangeListener android.view.ViewTreeObserver.OnPreDrawListener {
-    method public static androidx.core.view.OneShotPreDrawListener add(android.view.View, Runnable);
-    method public boolean onPreDraw();
-    method public void onViewAttachedToWindow(android.view.View);
-    method public void onViewDetachedFromWindow(android.view.View);
-    method public void removeListener();
-  }
-
-  public final class PointerIconCompat {
-    method public static androidx.core.view.PointerIconCompat create(android.graphics.Bitmap, float, float);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public Object? getPointerIcon();
-    method public static androidx.core.view.PointerIconCompat getSystemIcon(android.content.Context, int);
-    method public static androidx.core.view.PointerIconCompat load(android.content.res.Resources, int);
-    field public static final int TYPE_ALIAS = 1010; // 0x3f2
-    field public static final int TYPE_ALL_SCROLL = 1013; // 0x3f5
-    field public static final int TYPE_ARROW = 1000; // 0x3e8
-    field public static final int TYPE_CELL = 1006; // 0x3ee
-    field public static final int TYPE_CONTEXT_MENU = 1001; // 0x3e9
-    field public static final int TYPE_COPY = 1011; // 0x3f3
-    field public static final int TYPE_CROSSHAIR = 1007; // 0x3ef
-    field public static final int TYPE_DEFAULT = 1000; // 0x3e8
-    field public static final int TYPE_GRAB = 1020; // 0x3fc
-    field public static final int TYPE_GRABBING = 1021; // 0x3fd
-    field public static final int TYPE_HAND = 1002; // 0x3ea
-    field public static final int TYPE_HELP = 1003; // 0x3eb
-    field public static final int TYPE_HORIZONTAL_DOUBLE_ARROW = 1014; // 0x3f6
-    field public static final int TYPE_NO_DROP = 1012; // 0x3f4
-    field public static final int TYPE_NULL = 0; // 0x0
-    field public static final int TYPE_TEXT = 1008; // 0x3f0
-    field public static final int TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW = 1017; // 0x3f9
-    field public static final int TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW = 1016; // 0x3f8
-    field public static final int TYPE_VERTICAL_DOUBLE_ARROW = 1015; // 0x3f7
-    field public static final int TYPE_VERTICAL_TEXT = 1009; // 0x3f1
-    field public static final int TYPE_WAIT = 1004; // 0x3ec
-    field public static final int TYPE_ZOOM_IN = 1018; // 0x3fa
-    field public static final int TYPE_ZOOM_OUT = 1019; // 0x3fb
-  }
-
-  public final class ScaleGestureDetectorCompat {
-    method @Deprecated public static boolean isQuickScaleEnabled(Object!);
-    method public static boolean isQuickScaleEnabled(android.view.ScaleGestureDetector);
-    method @Deprecated public static void setQuickScaleEnabled(Object!, boolean);
-    method public static void setQuickScaleEnabled(android.view.ScaleGestureDetector, boolean);
-  }
-
-  public interface ScrollingView {
-    method public int computeHorizontalScrollExtent();
-    method public int computeHorizontalScrollOffset();
-    method public int computeHorizontalScrollRange();
-    method public int computeVerticalScrollExtent();
-    method public int computeVerticalScrollOffset();
-    method public int computeVerticalScrollRange();
-  }
-
-  public interface TintableBackgroundView {
-    method public android.content.res.ColorStateList? getSupportBackgroundTintList();
-    method public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
-    method public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
-    method public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
-  }
-
-  @Deprecated public final class VelocityTrackerCompat {
-    method @Deprecated public static float getXVelocity(android.view.VelocityTracker!, int);
-    method @Deprecated public static float getYVelocity(android.view.VelocityTracker!, int);
-  }
-
-  public class ViewCompat {
-    ctor @Deprecated protected ViewCompat();
-    method public static int addAccessibilityAction(android.view.View, CharSequence, androidx.core.view.accessibility.AccessibilityViewCommand);
-    method public static void addKeyboardNavigationClusters(android.view.View, java.util.Collection<android.view.View!>, int);
-    method public static void addOnUnhandledKeyEventListener(android.view.View, androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat);
-    method public static androidx.core.view.ViewPropertyAnimatorCompat animate(android.view.View);
-    method @Deprecated public static boolean canScrollHorizontally(android.view.View!, int);
-    method @Deprecated public static boolean canScrollVertically(android.view.View!, int);
-    method public static void cancelDragAndDrop(android.view.View);
-    method @Deprecated public static int combineMeasuredStates(int, int);
-    method public static androidx.core.view.WindowInsetsCompat computeSystemWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat, android.graphics.Rect);
-    method public static androidx.core.view.WindowInsetsCompat dispatchApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
-    method public static void dispatchFinishTemporaryDetach(android.view.View);
-    method public static boolean dispatchNestedFling(android.view.View, float, float, boolean);
-    method public static boolean dispatchNestedPreFling(android.view.View, float, float);
-    method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[]?, int[]?);
-    method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[]?, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]?);
-    method public static void dispatchNestedScroll(android.view.View, int, int, int, int, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int, int[]);
-    method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]?, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public static void dispatchStartTemporaryDetach(android.view.View);
-    method public static void enableAccessibleClickableSpanSupport(android.view.View);
-    method public static int generateViewId();
-    method public static androidx.core.view.AccessibilityDelegateCompat? getAccessibilityDelegate(android.view.View);
-    method public static int getAccessibilityLiveRegion(android.view.View);
-    method public static androidx.core.view.accessibility.AccessibilityNodeProviderCompat? getAccessibilityNodeProvider(android.view.View);
-    method @UiThread public static CharSequence? getAccessibilityPaneTitle(android.view.View);
-    method @Deprecated public static float getAlpha(android.view.View!);
-    method public static android.content.res.ColorStateList? getBackgroundTintList(android.view.View);
-    method public static android.graphics.PorterDuff.Mode? getBackgroundTintMode(android.view.View);
-    method public static android.graphics.Rect? getClipBounds(android.view.View);
-    method public static android.view.Display? getDisplay(android.view.View);
-    method public static float getElevation(android.view.View);
-    method public static boolean getFitsSystemWindows(android.view.View);
-    method public static int getImportantForAccessibility(android.view.View);
-    method public static int getImportantForAutofill(android.view.View);
-    method public static int getLabelFor(android.view.View);
-    method @Deprecated public static int getLayerType(android.view.View!);
-    method public static int getLayoutDirection(android.view.View);
-    method @Deprecated public static android.graphics.Matrix? getMatrix(android.view.View!);
-    method @Deprecated public static int getMeasuredHeightAndState(android.view.View!);
-    method @Deprecated public static int getMeasuredState(android.view.View!);
-    method @Deprecated public static int getMeasuredWidthAndState(android.view.View!);
-    method public static int getMinimumHeight(android.view.View);
-    method public static int getMinimumWidth(android.view.View);
-    method public static int getNextClusterForwardId(android.view.View);
-    method public static String![]? getOnReceiveContentMimeTypes(android.view.View);
-    method @Deprecated public static int getOverScrollMode(android.view.View!);
-    method @Px public static int getPaddingEnd(android.view.View);
-    method @Px public static int getPaddingStart(android.view.View);
-    method public static android.view.ViewParent? getParentForAccessibility(android.view.View);
-    method @Deprecated public static float getPivotX(android.view.View!);
-    method @Deprecated public static float getPivotY(android.view.View!);
-    method public static androidx.core.view.WindowInsetsCompat? getRootWindowInsets(android.view.View);
-    method @Deprecated public static float getRotation(android.view.View!);
-    method @Deprecated public static float getRotationX(android.view.View!);
-    method @Deprecated public static float getRotationY(android.view.View!);
-    method @Deprecated public static float getScaleX(android.view.View!);
-    method @Deprecated public static float getScaleY(android.view.View!);
-    method public static int getScrollIndicators(android.view.View);
-    method @UiThread public static CharSequence? getStateDescription(android.view.View);
-    method public static java.util.List<android.graphics.Rect!> getSystemGestureExclusionRects(android.view.View);
-    method public static String? getTransitionName(android.view.View);
-    method @Deprecated public static float getTranslationX(android.view.View!);
-    method @Deprecated public static float getTranslationY(android.view.View!);
-    method public static float getTranslationZ(android.view.View);
-    method @Deprecated public static androidx.core.view.WindowInsetsControllerCompat? getWindowInsetsController(android.view.View);
-    method @Deprecated public static int getWindowSystemUiVisibility(android.view.View);
-    method @Deprecated public static float getX(android.view.View!);
-    method @Deprecated public static float getY(android.view.View!);
-    method public static float getZ(android.view.View);
-    method public static boolean hasAccessibilityDelegate(android.view.View);
-    method public static boolean hasExplicitFocusable(android.view.View);
-    method public static boolean hasNestedScrollingParent(android.view.View);
-    method public static boolean hasNestedScrollingParent(android.view.View, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public static boolean hasOnClickListeners(android.view.View);
-    method public static boolean hasOverlappingRendering(android.view.View);
-    method public static boolean hasTransientState(android.view.View);
-    method @UiThread public static boolean isAccessibilityHeading(android.view.View);
-    method public static boolean isAttachedToWindow(android.view.View);
-    method public static boolean isFocusedByDefault(android.view.View);
-    method public static boolean isImportantForAccessibility(android.view.View);
-    method public static boolean isImportantForAutofill(android.view.View);
-    method public static boolean isInLayout(android.view.View);
-    method public static boolean isKeyboardNavigationCluster(android.view.View);
-    method public static boolean isLaidOut(android.view.View);
-    method public static boolean isLayoutDirectionResolved(android.view.View);
-    method public static boolean isNestedScrollingEnabled(android.view.View);
-    method @Deprecated public static boolean isOpaque(android.view.View!);
-    method public static boolean isPaddingRelative(android.view.View);
-    method @UiThread public static boolean isScreenReaderFocusable(android.view.View);
-    method @Deprecated public static void jumpDrawablesToCurrentState(android.view.View!);
-    method public static android.view.View? keyboardNavigationClusterSearch(android.view.View, android.view.View?, @androidx.core.view.ViewCompat.FocusDirection int);
-    method public static void offsetLeftAndRight(android.view.View, int);
-    method public static void offsetTopAndBottom(android.view.View, int);
-    method public static androidx.core.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
-    method @Deprecated public static void onInitializeAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
-    method public static void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
-    method @Deprecated public static void onPopulateAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
-    method public static boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
-    method public static androidx.core.view.ContentInfoCompat? performReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
-    method public static void postInvalidateOnAnimation(android.view.View);
-    method public static void postInvalidateOnAnimation(android.view.View, int, int, int, int);
-    method public static void postOnAnimation(android.view.View, Runnable);
-    method public static void postOnAnimationDelayed(android.view.View, Runnable, long);
-    method public static void removeAccessibilityAction(android.view.View, int);
-    method public static void removeOnUnhandledKeyEventListener(android.view.View, androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat);
-    method public static void replaceAccessibilityAction(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat, CharSequence?, androidx.core.view.accessibility.AccessibilityViewCommand?);
-    method public static void requestApplyInsets(android.view.View);
-    method public static <T extends android.view.View> T requireViewById(android.view.View, @IdRes int);
-    method @Deprecated public static int resolveSizeAndState(int, int, int);
-    method public static boolean restoreDefaultFocus(android.view.View);
-    method public static void saveAttributeDataForStyleable(android.view.View, android.content.Context, int[], android.util.AttributeSet?, android.content.res.TypedArray, int, int);
-    method public static void setAccessibilityDelegate(android.view.View, androidx.core.view.AccessibilityDelegateCompat?);
-    method @UiThread public static void setAccessibilityHeading(android.view.View, boolean);
-    method public static void setAccessibilityLiveRegion(android.view.View, int);
-    method @UiThread public static void setAccessibilityPaneTitle(android.view.View, CharSequence?);
-    method @Deprecated public static void setActivated(android.view.View!, boolean);
-    method @Deprecated public static void setAlpha(android.view.View!, @FloatRange(from=0.0, to=1.0) float);
-    method public static void setAutofillHints(android.view.View, java.lang.String!...);
-    method public static void setBackground(android.view.View, android.graphics.drawable.Drawable?);
-    method public static void setBackgroundTintList(android.view.View, android.content.res.ColorStateList?);
-    method public static void setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode?);
-    method @Deprecated public static void setChildrenDrawingOrderEnabled(android.view.ViewGroup!, boolean);
-    method public static void setClipBounds(android.view.View, android.graphics.Rect?);
-    method public static void setElevation(android.view.View, float);
-    method @Deprecated public static void setFitsSystemWindows(android.view.View!, boolean);
-    method public static void setFocusedByDefault(android.view.View, boolean);
-    method public static void setHasTransientState(android.view.View, boolean);
-    method @UiThread public static void setImportantForAccessibility(android.view.View, int);
-    method public static void setImportantForAutofill(android.view.View, int);
-    method public static void setKeyboardNavigationCluster(android.view.View, boolean);
-    method public static void setLabelFor(android.view.View, @IdRes int);
-    method public static void setLayerPaint(android.view.View, android.graphics.Paint?);
-    method @Deprecated public static void setLayerType(android.view.View!, int, android.graphics.Paint!);
-    method public static void setLayoutDirection(android.view.View, int);
-    method public static void setNestedScrollingEnabled(android.view.View, boolean);
-    method public static void setNextClusterForwardId(android.view.View, int);
-    method public static void setOnApplyWindowInsetsListener(android.view.View, androidx.core.view.OnApplyWindowInsetsListener?);
-    method public static void setOnReceiveContentListener(android.view.View, String![]?, androidx.core.view.OnReceiveContentListener?);
-    method @Deprecated public static void setOverScrollMode(android.view.View!, int);
-    method public static void setPaddingRelative(android.view.View, @Px int, @Px int, @Px int, @Px int);
-    method @Deprecated public static void setPivotX(android.view.View!, float);
-    method @Deprecated public static void setPivotY(android.view.View!, float);
-    method public static void setPointerIcon(android.view.View, androidx.core.view.PointerIconCompat?);
-    method @Deprecated public static void setRotation(android.view.View!, float);
-    method @Deprecated public static void setRotationX(android.view.View!, float);
-    method @Deprecated public static void setRotationY(android.view.View!, float);
-    method @Deprecated public static void setSaveFromParentEnabled(android.view.View!, boolean);
-    method @Deprecated public static void setScaleX(android.view.View!, float);
-    method @Deprecated public static void setScaleY(android.view.View!, float);
-    method @UiThread public static void setScreenReaderFocusable(android.view.View, boolean);
-    method public static void setScrollIndicators(android.view.View, @androidx.core.view.ViewCompat.ScrollIndicators int);
-    method public static void setScrollIndicators(android.view.View, @androidx.core.view.ViewCompat.ScrollIndicators int, @androidx.core.view.ViewCompat.ScrollIndicators int);
-    method @UiThread public static void setStateDescription(android.view.View, CharSequence?);
-    method public static void setSystemGestureExclusionRects(android.view.View, java.util.List<android.graphics.Rect!>);
-    method public static void setTooltipText(android.view.View, CharSequence?);
-    method public static void setTransitionName(android.view.View, String?);
-    method @Deprecated public static void setTranslationX(android.view.View!, float);
-    method @Deprecated public static void setTranslationY(android.view.View!, float);
-    method public static void setTranslationZ(android.view.View, float);
-    method public static void setWindowInsetsAnimationCallback(android.view.View, androidx.core.view.WindowInsetsAnimationCompat.Callback?);
-    method @Deprecated public static void setX(android.view.View!, float);
-    method @Deprecated public static void setY(android.view.View!, float);
-    method public static void setZ(android.view.View, float);
-    method public static boolean startDragAndDrop(android.view.View, android.content.ClipData?, android.view.View.DragShadowBuilder, Object?, int);
-    method public static boolean startNestedScroll(android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int);
-    method public static boolean startNestedScroll(android.view.View, @androidx.core.view.ViewCompat.ScrollAxis int, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public static void stopNestedScroll(android.view.View);
-    method public static void stopNestedScroll(android.view.View, @androidx.core.view.ViewCompat.NestedScrollType int);
-    method public static void updateDragShadow(android.view.View, android.view.View.DragShadowBuilder);
-    field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
-    field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
-    field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
-    field public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0; // 0x0
-    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 2; // 0x2
-    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 4; // 0x4
-    field public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 1; // 0x1
-    field @Deprecated public static final int LAYER_TYPE_HARDWARE = 2; // 0x2
-    field @Deprecated public static final int LAYER_TYPE_NONE = 0; // 0x0
-    field @Deprecated public static final int LAYER_TYPE_SOFTWARE = 1; // 0x1
-    field public static final int LAYOUT_DIRECTION_INHERIT = 2; // 0x2
-    field public static final int LAYOUT_DIRECTION_LOCALE = 3; // 0x3
-    field public static final int LAYOUT_DIRECTION_LTR = 0; // 0x0
-    field public static final int LAYOUT_DIRECTION_RTL = 1; // 0x1
-    field @Deprecated public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
-    field @Deprecated public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
-    field @Deprecated public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
-    field @Deprecated public static final int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
-    field @Deprecated public static final int OVER_SCROLL_ALWAYS = 0; // 0x0
-    field @Deprecated public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; // 0x1
-    field @Deprecated public static final int OVER_SCROLL_NEVER = 2; // 0x2
-    field public static final int SCROLL_AXIS_HORIZONTAL = 1; // 0x1
-    field public static final int SCROLL_AXIS_NONE = 0; // 0x0
-    field public static final int SCROLL_AXIS_VERTICAL = 2; // 0x2
-    field public static final int SCROLL_INDICATOR_BOTTOM = 2; // 0x2
-    field public static final int SCROLL_INDICATOR_END = 32; // 0x20
-    field public static final int SCROLL_INDICATOR_LEFT = 4; // 0x4
-    field public static final int SCROLL_INDICATOR_RIGHT = 8; // 0x8
-    field public static final int SCROLL_INDICATOR_START = 16; // 0x10
-    field public static final int SCROLL_INDICATOR_TOP = 1; // 0x1
-    field public static final int TYPE_NON_TOUCH = 1; // 0x1
-    field public static final int TYPE_TOUCH = 0; // 0x0
-  }
-
-  @IntDef({android.view.View.FOCUS_LEFT, android.view.View.FOCUS_UP, android.view.View.FOCUS_RIGHT, android.view.View.FOCUS_DOWN, android.view.View.FOCUS_FORWARD, android.view.View.FOCUS_BACKWARD}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewCompat.FocusDirection {
-  }
-
-  @IntDef({android.view.View.FOCUS_LEFT, android.view.View.FOCUS_UP, android.view.View.FOCUS_RIGHT, android.view.View.FOCUS_DOWN}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewCompat.FocusRealDirection {
-  }
-
-  @IntDef({android.view.View.FOCUS_FORWARD, android.view.View.FOCUS_BACKWARD}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewCompat.FocusRelativeDirection {
-  }
-
-  @IntDef({androidx.core.view.ViewCompat.TYPE_TOUCH, androidx.core.view.ViewCompat.TYPE_NON_TOUCH}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewCompat.NestedScrollType {
-  }
-
-  public static interface ViewCompat.OnUnhandledKeyEventListenerCompat {
-    method public boolean onUnhandledKeyEvent(android.view.View, android.view.KeyEvent);
-  }
-
-  @IntDef(value={androidx.core.view.ViewCompat.SCROLL_AXIS_NONE, androidx.core.view.ViewCompat.SCROLL_AXIS_HORIZONTAL, androidx.core.view.ViewCompat.SCROLL_AXIS_VERTICAL}, flag=true) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewCompat.ScrollAxis {
-  }
-
-  @IntDef(flag=true, value={androidx.core.view.ViewCompat.SCROLL_INDICATOR_TOP, androidx.core.view.ViewCompat.SCROLL_INDICATOR_BOTTOM, androidx.core.view.ViewCompat.SCROLL_INDICATOR_LEFT, androidx.core.view.ViewCompat.SCROLL_INDICATOR_RIGHT, androidx.core.view.ViewCompat.SCROLL_INDICATOR_START, androidx.core.view.ViewCompat.SCROLL_INDICATOR_END}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface ViewCompat.ScrollIndicators {
-  }
-
-  public final class ViewConfigurationCompat {
-    method public static float getScaledHorizontalScrollFactor(android.view.ViewConfiguration, android.content.Context);
-    method public static int getScaledHoverSlop(android.view.ViewConfiguration);
-    method @Deprecated public static int getScaledPagingTouchSlop(android.view.ViewConfiguration!);
-    method public static float getScaledVerticalScrollFactor(android.view.ViewConfiguration, android.content.Context);
-    method @Deprecated public static boolean hasPermanentMenuKey(android.view.ViewConfiguration!);
-    method public static boolean shouldShowMenuShortcutsWhenKeyboardPresent(android.view.ViewConfiguration, android.content.Context);
-  }
-
-  public final class ViewGroupCompat {
-    method public static int getLayoutMode(android.view.ViewGroup);
-    method @androidx.core.view.ViewCompat.ScrollAxis public static int getNestedScrollAxes(android.view.ViewGroup);
-    method public static boolean isTransitionGroup(android.view.ViewGroup);
-    method @Deprecated public static boolean onRequestSendAccessibilityEvent(android.view.ViewGroup!, android.view.View!, android.view.accessibility.AccessibilityEvent!);
-    method public static void setLayoutMode(android.view.ViewGroup, int);
-    method @Deprecated public static void setMotionEventSplittingEnabled(android.view.ViewGroup!, boolean);
-    method public static void setTransitionGroup(android.view.ViewGroup, boolean);
-    field public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; // 0x0
-    field public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; // 0x1
-  }
-
-  public final class ViewParentCompat {
-    method public static void notifySubtreeAccessibilityStateChanged(android.view.ViewParent, android.view.View, android.view.View, int);
-    method public static boolean onNestedFling(android.view.ViewParent, android.view.View, float, float, boolean);
-    method public static boolean onNestedPreFling(android.view.ViewParent, android.view.View, float, float);
-    method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[]);
-    method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[], int);
-    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int);
-    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int);
-    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int, int[]);
-    method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int);
-    method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int, int);
-    method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int);
-    method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int, int);
-    method public static void onStopNestedScroll(android.view.ViewParent, android.view.View);
-    method public static void onStopNestedScroll(android.view.ViewParent, android.view.View, int);
-    method @Deprecated public static boolean requestSendAccessibilityEvent(android.view.ViewParent!, android.view.View!, android.view.accessibility.AccessibilityEvent!);
-  }
-
-  public final class ViewPropertyAnimatorCompat {
-    method public androidx.core.view.ViewPropertyAnimatorCompat alpha(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat alphaBy(float);
-    method public void cancel();
-    method public long getDuration();
-    method public android.view.animation.Interpolator? getInterpolator();
-    method public long getStartDelay();
-    method public androidx.core.view.ViewPropertyAnimatorCompat rotation(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat rotationBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat rotationX(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat rotationXBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat rotationY(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat rotationYBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat scaleX(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat scaleXBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat scaleY(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat scaleYBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat setDuration(long);
-    method public androidx.core.view.ViewPropertyAnimatorCompat setInterpolator(android.view.animation.Interpolator?);
-    method public androidx.core.view.ViewPropertyAnimatorCompat setListener(androidx.core.view.ViewPropertyAnimatorListener?);
-    method public androidx.core.view.ViewPropertyAnimatorCompat setStartDelay(long);
-    method public androidx.core.view.ViewPropertyAnimatorCompat setUpdateListener(androidx.core.view.ViewPropertyAnimatorUpdateListener?);
-    method public void start();
-    method public androidx.core.view.ViewPropertyAnimatorCompat translationX(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat translationXBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat translationY(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat translationYBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat translationZ(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat translationZBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat withEndAction(Runnable);
-    method public androidx.core.view.ViewPropertyAnimatorCompat withLayer();
-    method public androidx.core.view.ViewPropertyAnimatorCompat withStartAction(Runnable);
-    method public androidx.core.view.ViewPropertyAnimatorCompat x(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat xBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat y(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat yBy(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat z(float);
-    method public androidx.core.view.ViewPropertyAnimatorCompat zBy(float);
-  }
-
-  public interface ViewPropertyAnimatorListener {
-    method public void onAnimationCancel(android.view.View);
-    method public void onAnimationEnd(android.view.View);
-    method public void onAnimationStart(android.view.View);
-  }
-
-  public class ViewPropertyAnimatorListenerAdapter implements androidx.core.view.ViewPropertyAnimatorListener {
-    ctor public ViewPropertyAnimatorListenerAdapter();
-    method public void onAnimationCancel(android.view.View);
-    method public void onAnimationEnd(android.view.View);
-    method public void onAnimationStart(android.view.View);
-  }
-
-  public interface ViewPropertyAnimatorUpdateListener {
-    method public void onAnimationUpdate(android.view.View);
-  }
-
-  public final class WindowCompat {
-    method public static androidx.core.view.WindowInsetsControllerCompat getInsetsController(android.view.Window, android.view.View);
-    method public static <T extends android.view.View> T requireViewById(android.view.Window, @IdRes int);
-    method public static void setDecorFitsSystemWindows(android.view.Window, boolean);
-    field public static final int FEATURE_ACTION_BAR = 8; // 0x8
-    field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
-    field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
-  }
-
-  public final class WindowInsetsAnimationCompat {
-    ctor public WindowInsetsAnimationCompat(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int, android.view.animation.Interpolator?, long);
-    method @FloatRange(from=0.0f, to=1.0f) public float getAlpha();
-    method public long getDurationMillis();
-    method @FloatRange(from=0.0f, to=1.0f) public float getFraction();
-    method public float getInterpolatedFraction();
-    method public android.view.animation.Interpolator? getInterpolator();
-    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public int getTypeMask();
-    method public void setAlpha(@FloatRange(from=0.0f, to=1.0f) float);
-    method public void setFraction(@FloatRange(from=0.0f, to=1.0f) float);
-  }
-
-  public static final class WindowInsetsAnimationCompat.BoundsCompat {
-    ctor public WindowInsetsAnimationCompat.BoundsCompat(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
-    method public androidx.core.graphics.Insets getLowerBound();
-    method public androidx.core.graphics.Insets getUpperBound();
-    method public androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat inset(androidx.core.graphics.Insets);
-    method @RequiresApi(30) public android.view.WindowInsetsAnimation.Bounds toBounds();
-    method @RequiresApi(30) public static androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat toBoundsCompat(android.view.WindowInsetsAnimation.Bounds);
-  }
-
-  public abstract static class WindowInsetsAnimationCompat.Callback {
-    ctor public WindowInsetsAnimationCompat.Callback(@androidx.core.view.WindowInsetsAnimationCompat.Callback.DispatchMode int);
-    method @androidx.core.view.WindowInsetsAnimationCompat.Callback.DispatchMode public final int getDispatchMode();
-    method public void onEnd(androidx.core.view.WindowInsetsAnimationCompat);
-    method public void onPrepare(androidx.core.view.WindowInsetsAnimationCompat);
-    method public abstract androidx.core.view.WindowInsetsCompat onProgress(androidx.core.view.WindowInsetsCompat, java.util.List<androidx.core.view.WindowInsetsAnimationCompat!>);
-    method public androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat onStart(androidx.core.view.WindowInsetsAnimationCompat, androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat);
-    field public static final int DISPATCH_MODE_CONTINUE_ON_SUBTREE = 1; // 0x1
-    field public static final int DISPATCH_MODE_STOP = 0; // 0x0
-  }
-
-  @IntDef({androidx.core.view.WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_STOP, androidx.core.view.WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_CONTINUE_ON_SUBTREE}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface WindowInsetsAnimationCompat.Callback.DispatchMode {
-  }
-
-  public interface WindowInsetsAnimationControlListenerCompat {
-    method public void onCancelled(androidx.core.view.WindowInsetsAnimationControllerCompat?);
-    method public void onFinished(androidx.core.view.WindowInsetsAnimationControllerCompat);
-    method public void onReady(androidx.core.view.WindowInsetsAnimationControllerCompat, @androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
-  }
-
-  public final class WindowInsetsAnimationControllerCompat {
-    method public void finish(boolean);
-    method public float getCurrentAlpha();
-    method @FloatRange(from=0.0f, to=1.0f) public float getCurrentFraction();
-    method public androidx.core.graphics.Insets getCurrentInsets();
-    method public androidx.core.graphics.Insets getHiddenStateInsets();
-    method public androidx.core.graphics.Insets getShownStateInsets();
-    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public int getTypes();
-    method public boolean isCancelled();
-    method public boolean isFinished();
-    method public boolean isReady();
-    method public void setInsetsAndAlpha(androidx.core.graphics.Insets?, @FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float);
-  }
-
-  public class WindowInsetsCompat {
-    ctor public WindowInsetsCompat(androidx.core.view.WindowInsetsCompat?);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeDisplayCutout();
-    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeStableInsets();
-    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeSystemWindowInsets();
-    method public androidx.core.view.DisplayCutoutCompat? getDisplayCutout();
-    method public androidx.core.graphics.Insets getInsets(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
-    method public androidx.core.graphics.Insets getInsetsIgnoringVisibility(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
-    method @Deprecated public androidx.core.graphics.Insets getMandatorySystemGestureInsets();
-    method @Deprecated public int getStableInsetBottom();
-    method @Deprecated public int getStableInsetLeft();
-    method @Deprecated public int getStableInsetRight();
-    method @Deprecated public int getStableInsetTop();
-    method @Deprecated public androidx.core.graphics.Insets getStableInsets();
-    method @Deprecated public androidx.core.graphics.Insets getSystemGestureInsets();
-    method @Deprecated public int getSystemWindowInsetBottom();
-    method @Deprecated public int getSystemWindowInsetLeft();
-    method @Deprecated public int getSystemWindowInsetRight();
-    method @Deprecated public int getSystemWindowInsetTop();
-    method @Deprecated public androidx.core.graphics.Insets getSystemWindowInsets();
-    method @Deprecated public androidx.core.graphics.Insets getTappableElementInsets();
-    method public boolean hasInsets();
-    method @Deprecated public boolean hasStableInsets();
-    method @Deprecated public boolean hasSystemWindowInsets();
-    method public androidx.core.view.WindowInsetsCompat inset(androidx.core.graphics.Insets);
-    method public androidx.core.view.WindowInsetsCompat inset(@IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int);
-    method public boolean isConsumed();
-    method public boolean isRound();
-    method public boolean isVisible(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat replaceSystemWindowInsets(int, int, int, int);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat replaceSystemWindowInsets(android.graphics.Rect);
-    method @RequiresApi(20) public android.view.WindowInsets? toWindowInsets();
-    method @RequiresApi(20) public static androidx.core.view.WindowInsetsCompat toWindowInsetsCompat(android.view.WindowInsets);
-    method @RequiresApi(20) public static androidx.core.view.WindowInsetsCompat toWindowInsetsCompat(android.view.WindowInsets, android.view.View?);
-    field public static final androidx.core.view.WindowInsetsCompat CONSUMED;
-  }
-
-  public static final class WindowInsetsCompat.Builder {
-    ctor public WindowInsetsCompat.Builder();
-    ctor public WindowInsetsCompat.Builder(androidx.core.view.WindowInsetsCompat);
-    method public androidx.core.view.WindowInsetsCompat build();
-    method public androidx.core.view.WindowInsetsCompat.Builder setDisplayCutout(androidx.core.view.DisplayCutoutCompat?);
-    method public androidx.core.view.WindowInsetsCompat.Builder setInsets(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int, androidx.core.graphics.Insets);
-    method public androidx.core.view.WindowInsetsCompat.Builder setInsetsIgnoringVisibility(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int, androidx.core.graphics.Insets);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setMandatorySystemGestureInsets(androidx.core.graphics.Insets);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setStableInsets(androidx.core.graphics.Insets);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setSystemGestureInsets(androidx.core.graphics.Insets);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setSystemWindowInsets(androidx.core.graphics.Insets);
-    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setTappableElementInsets(androidx.core.graphics.Insets);
-    method public androidx.core.view.WindowInsetsCompat.Builder setVisible(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int, boolean);
-  }
-
-  public static final class WindowInsetsCompat.Type {
-    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int captionBar();
-    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int displayCutout();
-    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int ime();
-    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int mandatorySystemGestures();
-    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int navigationBars();
-    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int statusBars();
-    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int systemBars();
-    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int systemGestures();
-    method @androidx.core.view.WindowInsetsCompat.Type.InsetsType public static int tappableElement();
-  }
-
-  @IntDef(flag=true, value={0x1, 0x2, 0x4, 0x8, 0x100, 0x10, 0x20, 0x40, 0x80}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface WindowInsetsCompat.Type.InsetsType {
-  }
-
-  public final class WindowInsetsControllerCompat {
-    ctor public WindowInsetsControllerCompat(android.view.Window, android.view.View);
-    method public void addOnControllableInsetsChangedListener(androidx.core.view.WindowInsetsControllerCompat.OnControllableInsetsChangedListener);
-    method public void controlWindowInsetsAnimation(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int, long, android.view.animation.Interpolator?, android.os.CancellationSignal?, androidx.core.view.WindowInsetsAnimationControlListenerCompat);
-    method public int getSystemBarsBehavior();
-    method public void hide(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
-    method public boolean isAppearanceLightNavigationBars();
-    method public boolean isAppearanceLightStatusBars();
-    method public void removeOnControllableInsetsChangedListener(androidx.core.view.WindowInsetsControllerCompat.OnControllableInsetsChangedListener);
-    method public void setAppearanceLightNavigationBars(boolean);
-    method public void setAppearanceLightStatusBars(boolean);
-    method public void setSystemBarsBehavior(int);
-    method public void show(@androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
-    method @Deprecated @RequiresApi(30) public static androidx.core.view.WindowInsetsControllerCompat toWindowInsetsControllerCompat(android.view.WindowInsetsController);
-    field public static final int BEHAVIOR_SHOW_BARS_BY_SWIPE = 1; // 0x1
-    field public static final int BEHAVIOR_SHOW_BARS_BY_TOUCH = 0; // 0x0
-    field public static final int BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE = 2; // 0x2
-  }
-
-  public static interface WindowInsetsControllerCompat.OnControllableInsetsChangedListener {
-    method public void onControllableInsetsChanged(androidx.core.view.WindowInsetsControllerCompat, @androidx.core.view.WindowInsetsCompat.Type.InsetsType int);
-  }
-
-}
-
-package androidx.core.view.accessibility {
-
-  public final class AccessibilityClickableSpanCompat extends android.text.style.ClickableSpan {
-    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public AccessibilityClickableSpanCompat(int, androidx.core.view.accessibility.AccessibilityNodeInfoCompat, int);
-    method public void onClick(android.view.View);
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final String SPAN_ID = "ACCESSIBILITY_CLICKABLE_SPAN_ID";
-  }
-
-  public final class AccessibilityEventCompat {
-    method @Deprecated public static void appendRecord(android.view.accessibility.AccessibilityEvent!, androidx.core.view.accessibility.AccessibilityRecordCompat!);
-    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! asRecord(android.view.accessibility.AccessibilityEvent!);
-    method public static int getAction(android.view.accessibility.AccessibilityEvent);
-    method @androidx.core.view.accessibility.AccessibilityEventCompat.ContentChangeType public static int getContentChangeTypes(android.view.accessibility.AccessibilityEvent);
-    method public static int getMovementGranularity(android.view.accessibility.AccessibilityEvent);
-    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! getRecord(android.view.accessibility.AccessibilityEvent!, int);
-    method @Deprecated public static int getRecordCount(android.view.accessibility.AccessibilityEvent!);
-    method public static void setAction(android.view.accessibility.AccessibilityEvent, int);
-    method public static void setContentChangeTypes(android.view.accessibility.AccessibilityEvent, @androidx.core.view.accessibility.AccessibilityEventCompat.ContentChangeType int);
-    method public static void setMovementGranularity(android.view.accessibility.AccessibilityEvent, int);
-    field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
-    field public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 16; // 0x10
-    field public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 32; // 0x20
-    field public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 8; // 0x8
-    field public static final int CONTENT_CHANGE_TYPE_STATE_DESCRIPTION = 64; // 0x40
-    field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
-    field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2
-    field public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0; // 0x0
-    field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
-    field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
-    field public static final int TYPE_ASSIST_READING_CONTEXT = 16777216; // 0x1000000
-    field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000
-    field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000
-    field @Deprecated public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400
-    field @Deprecated public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200
-    field public static final int TYPE_TOUCH_INTERACTION_END = 2097152; // 0x200000
-    field public static final int TYPE_TOUCH_INTERACTION_START = 1048576; // 0x100000
-    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 32768; // 0x8000
-    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 65536; // 0x10000
-    field public static final int TYPE_VIEW_CONTEXT_CLICKED = 8388608; // 0x800000
-    field @Deprecated public static final int TYPE_VIEW_HOVER_ENTER = 128; // 0x80
-    field @Deprecated public static final int TYPE_VIEW_HOVER_EXIT = 256; // 0x100
-    field @Deprecated public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
-    field @Deprecated public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
-    field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
-    field public static final int TYPE_WINDOWS_CHANGED = 4194304; // 0x400000
-    field @Deprecated public static final int TYPE_WINDOW_CONTENT_CHANGED = 2048; // 0x800
-  }
-
-  @IntDef(flag=true, value={androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_STATE_DESCRIPTION, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_SUBTREE, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_TEXT, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface AccessibilityEventCompat.ContentChangeType {
-  }
-
-  public final class AccessibilityManagerCompat {
-    method @Deprecated public static boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager!, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener!);
-    method public static boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
-    method @Deprecated public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo!>! getEnabledAccessibilityServiceList(android.view.accessibility.AccessibilityManager!, int);
-    method @Deprecated public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo!>! getInstalledAccessibilityServiceList(android.view.accessibility.AccessibilityManager!);
-    method @Deprecated public static boolean isTouchExplorationEnabled(android.view.accessibility.AccessibilityManager!);
-    method @Deprecated public static boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager!, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener!);
-    method public static boolean removeTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
-  }
-
-  @Deprecated public static interface AccessibilityManagerCompat.AccessibilityStateChangeListener {
-    method @Deprecated public void onAccessibilityStateChanged(boolean);
-  }
-
-  @Deprecated public abstract static class AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat implements androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener {
-    ctor @Deprecated public AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat();
-  }
-
-  public static interface AccessibilityManagerCompat.TouchExplorationStateChangeListener {
-    method public void onTouchExplorationStateChanged(boolean);
-  }
-
-  public class AccessibilityNodeInfoCompat {
-    ctor @Deprecated public AccessibilityNodeInfoCompat(Object!);
-    method public void addAction(int);
-    method public void addAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!);
-    method public void addChild(android.view.View!);
-    method public void addChild(android.view.View!, int);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void addSpansToExtras(CharSequence!, android.view.View!);
-    method public boolean canOpenPopup();
-    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>! findAccessibilityNodeInfosByText(String!);
-    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>! findAccessibilityNodeInfosByViewId(String!);
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! findFocus(int);
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! focusSearch(int);
-    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!>! getActionList();
-    method public int getActions();
-    method public java.util.List<java.lang.String!> getAvailableExtraData();
-    method @Deprecated public void getBoundsInParent(android.graphics.Rect!);
-    method public void getBoundsInScreen(android.graphics.Rect!);
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getChild(int);
-    method public int getChildCount();
-    method public CharSequence! getClassName();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.text.style.ClickableSpan![]! getClickableSpans(CharSequence!);
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! getCollectionInfo();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! getCollectionItemInfo();
-    method public CharSequence! getContentDescription();
-    method public int getDrawingOrder();
-    method public CharSequence! getError();
-    method public android.os.Bundle! getExtras();
-    method public CharSequence? getHintText();
-    method @Deprecated public Object! getInfo();
-    method public int getInputType();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabelFor();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabeledBy();
-    method public int getLiveRegion();
-    method public int getMaxTextLength();
-    method public int getMovementGranularities();
-    method public CharSequence! getPackageName();
-    method public CharSequence? getPaneTitle();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getParent();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat! getRangeInfo();
-    method public CharSequence? getRoleDescription();
-    method public CharSequence? getStateDescription();
-    method public CharSequence! getText();
-    method public int getTextSelectionEnd();
-    method public int getTextSelectionStart();
-    method public CharSequence? getTooltipText();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat? getTouchDelegateInfo();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalAfter();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalBefore();
-    method public String! getViewIdResourceName();
-    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat! getWindow();
-    method public int getWindowId();
-    method public boolean isAccessibilityFocused();
-    method public boolean isCheckable();
-    method public boolean isChecked();
-    method public boolean isClickable();
-    method public boolean isContentInvalid();
-    method public boolean isContextClickable();
-    method public boolean isDismissable();
-    method public boolean isEditable();
-    method public boolean isEnabled();
-    method public boolean isFocusable();
-    method public boolean isFocused();
-    method public boolean isHeading();
-    method public boolean isImportantForAccessibility();
-    method public boolean isLongClickable();
-    method public boolean isMultiLine();
-    method public boolean isPassword();
-    method public boolean isScreenReaderFocusable();
-    method public boolean isScrollable();
-    method public boolean isSelected();
-    method public boolean isShowingHintText();
-    method public boolean isTextEntryKey();
-    method public boolean isVisibleToUser();
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!);
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!, int);
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain();
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(androidx.core.view.accessibility.AccessibilityNodeInfoCompat!);
-    method public boolean performAction(int);
-    method public boolean performAction(int, android.os.Bundle!);
-    method public void recycle();
-    method public boolean refresh();
-    method public boolean removeAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!);
-    method public boolean removeChild(android.view.View!);
-    method public boolean removeChild(android.view.View!, int);
-    method public void setAccessibilityFocused(boolean);
-    method public void setAvailableExtraData(java.util.List<java.lang.String!>);
-    method @Deprecated public void setBoundsInParent(android.graphics.Rect!);
-    method public void setBoundsInScreen(android.graphics.Rect!);
-    method public void setCanOpenPopup(boolean);
-    method public void setCheckable(boolean);
-    method public void setChecked(boolean);
-    method public void setClassName(CharSequence!);
-    method public void setClickable(boolean);
-    method public void setCollectionInfo(Object!);
-    method public void setCollectionItemInfo(Object!);
-    method public void setContentDescription(CharSequence!);
-    method public void setContentInvalid(boolean);
-    method public void setContextClickable(boolean);
-    method public void setDismissable(boolean);
-    method public void setDrawingOrder(int);
-    method public void setEditable(boolean);
-    method public void setEnabled(boolean);
-    method public void setError(CharSequence!);
-    method public void setFocusable(boolean);
-    method public void setFocused(boolean);
-    method public void setHeading(boolean);
-    method public void setHintText(CharSequence?);
-    method public void setImportantForAccessibility(boolean);
-    method public void setInputType(int);
-    method public void setLabelFor(android.view.View!);
-    method public void setLabelFor(android.view.View!, int);
-    method public void setLabeledBy(android.view.View!);
-    method public void setLabeledBy(android.view.View!, int);
-    method public void setLiveRegion(int);
-    method public void setLongClickable(boolean);
-    method public void setMaxTextLength(int);
-    method public void setMovementGranularities(int);
-    method public void setMultiLine(boolean);
-    method public void setPackageName(CharSequence!);
-    method public void setPaneTitle(CharSequence?);
-    method public void setParent(android.view.View!);
-    method public void setParent(android.view.View!, int);
-    method public void setPassword(boolean);
-    method public void setRangeInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat!);
-    method public void setRoleDescription(CharSequence?);
-    method public void setScreenReaderFocusable(boolean);
-    method public void setScrollable(boolean);
-    method public void setSelected(boolean);
-    method public void setShowingHintText(boolean);
-    method public void setSource(android.view.View!);
-    method public void setSource(android.view.View!, int);
-    method public void setStateDescription(CharSequence?);
-    method public void setText(CharSequence!);
-    method public void setTextEntryKey(boolean);
-    method public void setTextSelection(int, int);
-    method public void setTooltipText(CharSequence?);
-    method public void setTouchDelegateInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat);
-    method public void setTraversalAfter(android.view.View!);
-    method public void setTraversalAfter(android.view.View!, int);
-    method public void setTraversalBefore(android.view.View!);
-    method public void setTraversalBefore(android.view.View!, int);
-    method public void setViewIdResourceName(String!);
-    method public void setVisibleToUser(boolean);
-    method public android.view.accessibility.AccessibilityNodeInfo! unwrap();
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! wrap(android.view.accessibility.AccessibilityNodeInfo);
-    field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
-    field public static final String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT";
-    field public static final String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
-    field public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
-    field public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
-    field public static final String ACTION_ARGUMENT_MOVE_WINDOW_X = "ACTION_ARGUMENT_MOVE_WINDOW_X";
-    field public static final String ACTION_ARGUMENT_MOVE_WINDOW_Y = "ACTION_ARGUMENT_MOVE_WINDOW_Y";
-    field public static final String ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT = "android.view.accessibility.action.ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT";
-    field public static final String ACTION_ARGUMENT_PROGRESS_VALUE = "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
-    field public static final String ACTION_ARGUMENT_ROW_INT = "android.view.accessibility.action.ARGUMENT_ROW_INT";
-    field public static final String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
-    field public static final String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
-    field public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
-    field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
-    field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
-    field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
-    field public static final int ACTION_CLICK = 16; // 0x10
-    field public static final int ACTION_COLLAPSE = 524288; // 0x80000
-    field public static final int ACTION_COPY = 16384; // 0x4000
-    field public static final int ACTION_CUT = 65536; // 0x10000
-    field public static final int ACTION_DISMISS = 1048576; // 0x100000
-    field public static final int ACTION_EXPAND = 262144; // 0x40000
-    field public static final int ACTION_FOCUS = 1; // 0x1
-    field public static final int ACTION_LONG_CLICK = 32; // 0x20
-    field public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 256; // 0x100
-    field public static final int ACTION_NEXT_HTML_ELEMENT = 1024; // 0x400
-    field public static final int ACTION_PASTE = 32768; // 0x8000
-    field public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 512; // 0x200
-    field public static final int ACTION_PREVIOUS_HTML_ELEMENT = 2048; // 0x800
-    field public static final int ACTION_SCROLL_BACKWARD = 8192; // 0x2000
-    field public static final int ACTION_SCROLL_FORWARD = 4096; // 0x1000
-    field public static final int ACTION_SELECT = 4; // 0x4
-    field public static final int ACTION_SET_SELECTION = 131072; // 0x20000
-    field public static final int ACTION_SET_TEXT = 2097152; // 0x200000
-    field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
-    field public static final int FOCUS_INPUT = 1; // 0x1
-    field public static final int MOVEMENT_GRANULARITY_CHARACTER = 1; // 0x1
-    field public static final int MOVEMENT_GRANULARITY_LINE = 4; // 0x4
-    field public static final int MOVEMENT_GRANULARITY_PAGE = 16; // 0x10
-    field public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 8; // 0x8
-    field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int mParentVirtualDescendantId;
-  }
-
-  public static class AccessibilityNodeInfoCompat.AccessibilityActionCompat {
-    ctor public AccessibilityNodeInfoCompat.AccessibilityActionCompat(int, CharSequence!);
-    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public AccessibilityNodeInfoCompat.AccessibilityActionCompat(int, CharSequence!, androidx.core.view.accessibility.AccessibilityViewCommand!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! createReplacementAction(CharSequence!, androidx.core.view.accessibility.AccessibilityViewCommand!);
-    method public int getId();
-    method public CharSequence! getLabel();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean perform(android.view.View!, android.os.Bundle!);
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_ACCESSIBILITY_FOCUS;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_ACCESSIBILITY_FOCUS;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_FOCUS;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_SELECTION;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLICK;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COLLAPSE;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CONTEXT_CLICK;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COPY;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CUT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_DISMISS;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_EXPAND;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_FOCUS;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_HIDE_TOOLTIP;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_IME_ENTER;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_LONG_CLICK;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_MOVE_WINDOW;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_HTML_ELEMENT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_DOWN;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_LEFT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_RIGHT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_UP;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PASTE;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PRESS_AND_HOLD;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_HTML_ELEMENT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_BACKWARD;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_DOWN;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_FORWARD;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_LEFT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_RIGHT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_TO_POSITION;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_UP;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SELECT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_PROGRESS;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_SELECTION;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_TEXT;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SHOW_ON_SCREEN;
-    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SHOW_TOOLTIP;
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) protected final androidx.core.view.accessibility.AccessibilityViewCommand! mCommand;
-  }
-
-  public static class AccessibilityNodeInfoCompat.CollectionInfoCompat {
-    method public int getColumnCount();
-    method public int getRowCount();
-    method public int getSelectionMode();
-    method public boolean isHierarchical();
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! obtain(int, int, boolean, int);
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! obtain(int, int, boolean);
-    field public static final int SELECTION_MODE_MULTIPLE = 2; // 0x2
-    field public static final int SELECTION_MODE_NONE = 0; // 0x0
-    field public static final int SELECTION_MODE_SINGLE = 1; // 0x1
-  }
-
-  public static class AccessibilityNodeInfoCompat.CollectionItemInfoCompat {
-    method public int getColumnIndex();
-    method public int getColumnSpan();
-    method public int getRowIndex();
-    method public int getRowSpan();
-    method @Deprecated public boolean isHeading();
-    method public boolean isSelected();
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! obtain(int, int, int, int, boolean, boolean);
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! obtain(int, int, int, int, boolean);
-  }
-
-  public static class AccessibilityNodeInfoCompat.RangeInfoCompat {
-    method public float getCurrent();
-    method public float getMax();
-    method public float getMin();
-    method public int getType();
-    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat! obtain(int, float, float, float);
-    field public static final int RANGE_TYPE_FLOAT = 1; // 0x1
-    field public static final int RANGE_TYPE_INT = 0; // 0x0
-    field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
-  }
-
-  public static final class AccessibilityNodeInfoCompat.TouchDelegateInfoCompat {
-    ctor public AccessibilityNodeInfoCompat.TouchDelegateInfoCompat(java.util.Map<android.graphics.Region!,android.view.View!>);
-    method public android.graphics.Region? getRegionAt(@IntRange(from=0) int);
-    method @IntRange(from=0) public int getRegionCount();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getTargetForRegion(android.graphics.Region);
-  }
-
-  public class AccessibilityNodeProviderCompat {
-    ctor public AccessibilityNodeProviderCompat();
-    ctor public AccessibilityNodeProviderCompat(Object?);
-    method public void addExtraDataToAccessibilityNodeInfo(int, androidx.core.view.accessibility.AccessibilityNodeInfoCompat, String, android.os.Bundle?);
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? createAccessibilityNodeInfo(int);
-    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>? findAccessibilityNodeInfosByText(String, int);
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? findFocus(int);
-    method public Object? getProvider();
-    method public boolean performAction(int, int, android.os.Bundle?);
-    field public static final int HOST_VIEW_ID = -1; // 0xffffffff
-  }
-
-  public class AccessibilityRecordCompat {
-    ctor @Deprecated public AccessibilityRecordCompat(Object!);
-    method @Deprecated public boolean equals(Object?);
-    method @Deprecated public int getAddedCount();
-    method @Deprecated public CharSequence! getBeforeText();
-    method @Deprecated public CharSequence! getClassName();
-    method @Deprecated public CharSequence! getContentDescription();
-    method @Deprecated public int getCurrentItemIndex();
-    method @Deprecated public int getFromIndex();
-    method @Deprecated public Object! getImpl();
-    method @Deprecated public int getItemCount();
-    method @Deprecated public int getMaxScrollX();
-    method public static int getMaxScrollX(android.view.accessibility.AccessibilityRecord);
-    method @Deprecated public int getMaxScrollY();
-    method public static int getMaxScrollY(android.view.accessibility.AccessibilityRecord);
-    method @Deprecated public android.os.Parcelable! getParcelableData();
-    method @Deprecated public int getRemovedCount();
-    method @Deprecated public int getScrollX();
-    method @Deprecated public int getScrollY();
-    method @Deprecated public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getSource();
-    method @Deprecated public java.util.List<java.lang.CharSequence!>! getText();
-    method @Deprecated public int getToIndex();
-    method @Deprecated public int getWindowId();
-    method @Deprecated public int hashCode();
-    method @Deprecated public boolean isChecked();
-    method @Deprecated public boolean isEnabled();
-    method @Deprecated public boolean isFullScreen();
-    method @Deprecated public boolean isPassword();
-    method @Deprecated public boolean isScrollable();
-    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! obtain(androidx.core.view.accessibility.AccessibilityRecordCompat!);
-    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! obtain();
-    method @Deprecated public void recycle();
-    method @Deprecated public void setAddedCount(int);
-    method @Deprecated public void setBeforeText(CharSequence!);
-    method @Deprecated public void setChecked(boolean);
-    method @Deprecated public void setClassName(CharSequence!);
-    method @Deprecated public void setContentDescription(CharSequence!);
-    method @Deprecated public void setCurrentItemIndex(int);
-    method @Deprecated public void setEnabled(boolean);
-    method @Deprecated public void setFromIndex(int);
-    method @Deprecated public void setFullScreen(boolean);
-    method @Deprecated public void setItemCount(int);
-    method @Deprecated public void setMaxScrollX(int);
-    method public static void setMaxScrollX(android.view.accessibility.AccessibilityRecord, int);
-    method @Deprecated public void setMaxScrollY(int);
-    method public static void setMaxScrollY(android.view.accessibility.AccessibilityRecord, int);
-    method @Deprecated public void setParcelableData(android.os.Parcelable!);
-    method @Deprecated public void setPassword(boolean);
-    method @Deprecated public void setRemovedCount(int);
-    method @Deprecated public void setScrollX(int);
-    method @Deprecated public void setScrollY(int);
-    method @Deprecated public void setScrollable(boolean);
-    method @Deprecated public void setSource(android.view.View!);
-    method @Deprecated public void setSource(android.view.View!, int);
-    method public static void setSource(android.view.accessibility.AccessibilityRecord, android.view.View?, int);
-    method @Deprecated public void setToIndex(int);
-  }
-
-  public interface AccessibilityViewCommand {
-    method public boolean perform(android.view.View, androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments?);
-  }
-
-  public abstract static class AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.CommandArguments();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setBundle(android.os.Bundle?);
-  }
-
-  public static final class AccessibilityViewCommand.MoveAtGranularityArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.MoveAtGranularityArguments();
-    method public boolean getExtendSelection();
-    method public int getGranularity();
-  }
-
-  public static final class AccessibilityViewCommand.MoveHtmlArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.MoveHtmlArguments();
-    method public String? getHTMLElement();
-  }
-
-  public static final class AccessibilityViewCommand.MoveWindowArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.MoveWindowArguments();
-    method public int getX();
-    method public int getY();
-  }
-
-  public static final class AccessibilityViewCommand.ScrollToPositionArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.ScrollToPositionArguments();
-    method public int getColumn();
-    method public int getRow();
-  }
-
-  public static final class AccessibilityViewCommand.SetProgressArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.SetProgressArguments();
-    method public float getProgress();
-  }
-
-  public static final class AccessibilityViewCommand.SetSelectionArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.SetSelectionArguments();
-    method public int getEnd();
-    method public int getStart();
-  }
-
-  public static final class AccessibilityViewCommand.SetTextArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
-    ctor public AccessibilityViewCommand.SetTextArguments();
-    method public CharSequence? getText();
-  }
-
-  public class AccessibilityWindowInfoCompat {
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getAnchor();
-    method public void getBoundsInScreen(android.graphics.Rect);
-    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getChild(int);
-    method public int getChildCount();
-    method public int getId();
-    method public int getLayer();
-    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getParent();
-    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getRoot();
-    method public CharSequence? getTitle();
-    method public int getType();
-    method public boolean isAccessibilityFocused();
-    method public boolean isActive();
-    method public boolean isFocused();
-    method public static androidx.core.view.accessibility.AccessibilityWindowInfoCompat? obtain();
-    method public static androidx.core.view.accessibility.AccessibilityWindowInfoCompat? obtain(androidx.core.view.accessibility.AccessibilityWindowInfoCompat?);
-    method public void recycle();
-    field public static final int TYPE_ACCESSIBILITY_OVERLAY = 4; // 0x4
-    field public static final int TYPE_APPLICATION = 1; // 0x1
-    field public static final int TYPE_INPUT_METHOD = 2; // 0x2
-    field public static final int TYPE_SPLIT_SCREEN_DIVIDER = 5; // 0x5
-    field public static final int TYPE_SYSTEM = 3; // 0x3
-  }
-
-}
-
-package androidx.core.view.animation {
-
-  public final class PathInterpolatorCompat {
-    method public static android.view.animation.Interpolator create(android.graphics.Path);
-    method public static android.view.animation.Interpolator create(float, float);
-    method public static android.view.animation.Interpolator create(float, float, float, float);
-  }
-
-}
-
-package androidx.core.view.inputmethod {
-
-  public final class EditorInfoCompat {
-    ctor @Deprecated public EditorInfoCompat();
-    method public static String![] getContentMimeTypes(android.view.inputmethod.EditorInfo);
-    method public static CharSequence? getInitialSelectedText(android.view.inputmethod.EditorInfo, int);
-    method public static CharSequence? getInitialTextAfterCursor(android.view.inputmethod.EditorInfo, int, int);
-    method public static CharSequence? getInitialTextBeforeCursor(android.view.inputmethod.EditorInfo, int, int);
-    method public static void setContentMimeTypes(android.view.inputmethod.EditorInfo, String![]?);
-    method public static void setInitialSurroundingSubText(android.view.inputmethod.EditorInfo, CharSequence, int);
-    method public static void setInitialSurroundingText(android.view.inputmethod.EditorInfo, CharSequence);
-    field public static final int IME_FLAG_FORCE_ASCII = -2147483648; // 0x80000000
-    field public static final int IME_FLAG_NO_PERSONALIZED_LEARNING = 16777216; // 0x1000000
-  }
-
-  public final class InputConnectionCompat {
-    ctor @Deprecated public InputConnectionCompat();
-    method public static boolean commitContent(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle?);
-    method @Deprecated public static android.view.inputmethod.InputConnection createWrapper(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputConnectionCompat.OnCommitContentListener);
-    method public static android.view.inputmethod.InputConnection createWrapper(android.view.View, android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo);
-    field public static final int INPUT_CONTENT_GRANT_READ_URI_PERMISSION = 1; // 0x1
-  }
-
-  public static interface InputConnectionCompat.OnCommitContentListener {
-    method public boolean onCommitContent(androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle?);
-  }
-
-  public final class InputContentInfoCompat {
-    ctor public InputContentInfoCompat(android.net.Uri, android.content.ClipDescription, android.net.Uri?);
-    method public android.net.Uri getContentUri();
-    method public android.content.ClipDescription getDescription();
-    method public android.net.Uri? getLinkUri();
-    method public void releasePermission();
-    method public void requestPermission();
-    method public Object? unwrap();
-    method public static androidx.core.view.inputmethod.InputContentInfoCompat? wrap(Object?);
-  }
-
-}
-
-package androidx.core.widget {
-
-  public abstract class AutoScrollHelper implements android.view.View.OnTouchListener {
-    ctor public AutoScrollHelper(android.view.View);
-    method public abstract boolean canTargetScrollHorizontally(int);
-    method public abstract boolean canTargetScrollVertically(int);
-    method public boolean isEnabled();
-    method public boolean isExclusive();
-    method public boolean onTouch(android.view.View!, android.view.MotionEvent!);
-    method public abstract void scrollTargetBy(int, int);
-    method public androidx.core.widget.AutoScrollHelper setActivationDelay(int);
-    method public androidx.core.widget.AutoScrollHelper setEdgeType(int);
-    method public androidx.core.widget.AutoScrollHelper! setEnabled(boolean);
-    method public androidx.core.widget.AutoScrollHelper! setExclusive(boolean);
-    method public androidx.core.widget.AutoScrollHelper setMaximumEdges(float, float);
-    method public androidx.core.widget.AutoScrollHelper setMaximumVelocity(float, float);
-    method public androidx.core.widget.AutoScrollHelper setMinimumVelocity(float, float);
-    method public androidx.core.widget.AutoScrollHelper setRampDownDuration(int);
-    method public androidx.core.widget.AutoScrollHelper setRampUpDuration(int);
-    method public androidx.core.widget.AutoScrollHelper setRelativeEdges(float, float);
-    method public androidx.core.widget.AutoScrollHelper setRelativeVelocity(float, float);
-    field public static final int EDGE_TYPE_INSIDE = 0; // 0x0
-    field public static final int EDGE_TYPE_INSIDE_EXTEND = 1; // 0x1
-    field public static final int EDGE_TYPE_OUTSIDE = 2; // 0x2
-    field public static final float NO_MAX = 3.4028235E38f;
-    field public static final float NO_MIN = 0.0f;
-    field public static final float RELATIVE_UNSPECIFIED = 0.0f;
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface AutoSizeableTextView {
-    method public int getAutoSizeMaxTextSize();
-    method public int getAutoSizeMinTextSize();
-    method public int getAutoSizeStepGranularity();
-    method public int[]! getAutoSizeTextAvailableSizes();
-    method @androidx.core.widget.TextViewCompat.AutoSizeTextType public int getAutoSizeTextType();
-    method public void setAutoSizeTextTypeUniformWithConfiguration(int, int, int, int) throws java.lang.IllegalArgumentException;
-    method public void setAutoSizeTextTypeUniformWithPresetSizes(int[], int) throws java.lang.IllegalArgumentException;
-    method public void setAutoSizeTextTypeWithDefaults(@androidx.core.widget.TextViewCompat.AutoSizeTextType int);
-    field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final boolean PLATFORM_SUPPORTS_AUTOSIZE;
-  }
-
-  public final class CheckedTextViewCompat {
-    method public static android.graphics.drawable.Drawable? getCheckMarkDrawable(android.widget.CheckedTextView);
-    method public static android.content.res.ColorStateList? getCheckMarkTintList(android.widget.CheckedTextView);
-    method public static android.graphics.PorterDuff.Mode? getCheckMarkTintMode(android.widget.CheckedTextView);
-    method public static void setCheckMarkTintList(android.widget.CheckedTextView, android.content.res.ColorStateList?);
-    method public static void setCheckMarkTintMode(android.widget.CheckedTextView, android.graphics.PorterDuff.Mode?);
-  }
-
-  public final class CompoundButtonCompat {
-    method public static android.graphics.drawable.Drawable? getButtonDrawable(android.widget.CompoundButton);
-    method public static android.content.res.ColorStateList? getButtonTintList(android.widget.CompoundButton);
-    method public static android.graphics.PorterDuff.Mode? getButtonTintMode(android.widget.CompoundButton);
-    method public static void setButtonTintList(android.widget.CompoundButton, android.content.res.ColorStateList?);
-    method public static void setButtonTintMode(android.widget.CompoundButton, android.graphics.PorterDuff.Mode?);
-  }
-
-  public class ContentLoadingProgressBar extends android.widget.ProgressBar {
-    ctor public ContentLoadingProgressBar(android.content.Context);
-    ctor public ContentLoadingProgressBar(android.content.Context, android.util.AttributeSet?);
-    method public void hide();
-    method public void onAttachedToWindow();
-    method public void onDetachedFromWindow();
-    method public void show();
-  }
-
-  public final class EdgeEffectCompat {
-    ctor @Deprecated public EdgeEffectCompat(android.content.Context!);
-    method public static android.widget.EdgeEffect create(android.content.Context, android.util.AttributeSet?);
-    method @Deprecated public boolean draw(android.graphics.Canvas!);
-    method @Deprecated public void finish();
-    method public static float getDistance(android.widget.EdgeEffect);
-    method @Deprecated public boolean isFinished();
-    method @Deprecated public boolean onAbsorb(int);
-    method @Deprecated public boolean onPull(float);
-    method @Deprecated public boolean onPull(float, float);
-    method public static void onPull(android.widget.EdgeEffect, float, float);
-    method public static float onPullDistance(android.widget.EdgeEffect, float, float);
-    method @Deprecated public boolean onRelease();
-    method @Deprecated public void setSize(int, int);
-  }
-
-  public class ImageViewCompat {
-    method public static android.content.res.ColorStateList? getImageTintList(android.widget.ImageView);
-    method public static android.graphics.PorterDuff.Mode? getImageTintMode(android.widget.ImageView);
-    method public static void setImageTintList(android.widget.ImageView, android.content.res.ColorStateList?);
-    method public static void setImageTintMode(android.widget.ImageView, android.graphics.PorterDuff.Mode?);
-  }
-
-  public final class ListPopupWindowCompat {
-    method @Deprecated public static android.view.View.OnTouchListener! createDragToOpenListener(Object!, android.view.View!);
-    method public static android.view.View.OnTouchListener? createDragToOpenListener(android.widget.ListPopupWindow, android.view.View);
-  }
-
-  public class ListViewAutoScrollHelper extends androidx.core.widget.AutoScrollHelper {
-    ctor public ListViewAutoScrollHelper(android.widget.ListView);
-    method public boolean canTargetScrollHorizontally(int);
-    method public boolean canTargetScrollVertically(int);
-    method public void scrollTargetBy(int, int);
-  }
-
-  public final class ListViewCompat {
-    method public static boolean canScrollList(android.widget.ListView, int);
-    method public static void scrollListBy(android.widget.ListView, int);
-  }
-
-  public class NestedScrollView extends android.widget.FrameLayout implements androidx.core.view.NestedScrollingChild3 androidx.core.view.NestedScrollingParent3 androidx.core.view.ScrollingView {
-    ctor public NestedScrollView(android.content.Context);
-    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet?);
-    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet?, int);
-    method public boolean arrowScroll(int);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollExtent();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollOffset();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollRange();
-    method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect!);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollExtent();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollOffset();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollRange();
-    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
-    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]);
-    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
-    method public boolean executeKeyEvent(android.view.KeyEvent);
-    method public void fling(int);
-    method public boolean fullScroll(int);
-    method public int getMaxScrollAmount();
-    method public boolean hasNestedScrollingParent(int);
-    method public boolean isFillViewport();
-    method public boolean isSmoothScrollingEnabled();
-    method public void onAttachedToWindow();
-    method public void onNestedPreScroll(android.view.View, int, int, int[], int);
-    method public void onNestedScroll(android.view.View, int, int, int, int, int, int[]);
-    method public void onNestedScroll(android.view.View, int, int, int, int, int);
-    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
-    method public boolean onStartNestedScroll(android.view.View, android.view.View, int, int);
-    method public void onStopNestedScroll(android.view.View, int);
-    method public boolean pageScroll(int);
-    method public void setFillViewport(boolean);
-    method public void setOnScrollChangeListener(androidx.core.widget.NestedScrollView.OnScrollChangeListener?);
-    method public void setSmoothScrollingEnabled(boolean);
-    method public final void smoothScrollBy(int, int);
-    method public final void smoothScrollBy(int, int, int);
-    method public final void smoothScrollTo(int, int);
-    method public final void smoothScrollTo(int, int, int);
-    method public boolean startNestedScroll(int, int);
-    method public void stopNestedScroll(int);
-  }
-
-  public static interface NestedScrollView.OnScrollChangeListener {
-    method public void onScrollChange(androidx.core.widget.NestedScrollView, int, int, int, int);
-  }
-
-  public final class PopupMenuCompat {
-    method public static android.view.View.OnTouchListener? getDragToOpenListener(Object);
-  }
-
-  public final class PopupWindowCompat {
-    method public static boolean getOverlapAnchor(android.widget.PopupWindow);
-    method public static int getWindowLayoutType(android.widget.PopupWindow);
-    method public static void setOverlapAnchor(android.widget.PopupWindow, boolean);
-    method public static void setWindowLayoutType(android.widget.PopupWindow, int);
-    method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
-  }
-
-  @Deprecated public final class ScrollerCompat {
-    method @Deprecated public void abortAnimation();
-    method @Deprecated public boolean computeScrollOffset();
-    method @Deprecated public static androidx.core.widget.ScrollerCompat! create(android.content.Context!);
-    method @Deprecated public static androidx.core.widget.ScrollerCompat! create(android.content.Context!, android.view.animation.Interpolator!);
-    method @Deprecated public void fling(int, int, int, int, int, int, int, int);
-    method @Deprecated public void fling(int, int, int, int, int, int, int, int, int, int);
-    method @Deprecated public float getCurrVelocity();
-    method @Deprecated public int getCurrX();
-    method @Deprecated public int getCurrY();
-    method @Deprecated public int getFinalX();
-    method @Deprecated public int getFinalY();
-    method @Deprecated public boolean isFinished();
-    method @Deprecated public boolean isOverScrolled();
-    method @Deprecated public void notifyHorizontalEdgeReached(int, int, int);
-    method @Deprecated public void notifyVerticalEdgeReached(int, int, int);
-    method @Deprecated public boolean springBack(int, int, int, int, int, int);
-    method @Deprecated public void startScroll(int, int, int, int);
-    method @Deprecated public void startScroll(int, int, int, int, int);
-  }
-
-  public final class TextViewCompat {
-    method public static int getAutoSizeMaxTextSize(android.widget.TextView);
-    method public static int getAutoSizeMinTextSize(android.widget.TextView);
-    method public static int getAutoSizeStepGranularity(android.widget.TextView);
-    method public static int[] getAutoSizeTextAvailableSizes(android.widget.TextView);
-    method public static int getAutoSizeTextType(android.widget.TextView);
-    method public static android.content.res.ColorStateList? getCompoundDrawableTintList(android.widget.TextView);
-    method public static android.graphics.PorterDuff.Mode? getCompoundDrawableTintMode(android.widget.TextView);
-    method public static android.graphics.drawable.Drawable![] getCompoundDrawablesRelative(android.widget.TextView);
-    method public static int getFirstBaselineToTopHeight(android.widget.TextView);
-    method public static int getLastBaselineToBottomHeight(android.widget.TextView);
-    method public static int getMaxLines(android.widget.TextView);
-    method public static int getMinLines(android.widget.TextView);
-    method public static androidx.core.text.PrecomputedTextCompat.Params getTextMetricsParams(android.widget.TextView);
-    method public static void setAutoSizeTextTypeUniformWithConfiguration(android.widget.TextView, int, int, int, int) throws java.lang.IllegalArgumentException;
-    method public static void setAutoSizeTextTypeUniformWithPresetSizes(android.widget.TextView, int[], int) throws java.lang.IllegalArgumentException;
-    method public static void setAutoSizeTextTypeWithDefaults(android.widget.TextView, int);
-    method public static void setCompoundDrawableTintList(android.widget.TextView, android.content.res.ColorStateList?);
-    method public static void setCompoundDrawableTintMode(android.widget.TextView, android.graphics.PorterDuff.Mode?);
-    method public static void setCompoundDrawablesRelative(android.widget.TextView, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?);
-    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?);
-    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, @DrawableRes int, @DrawableRes int, @DrawableRes int, @DrawableRes int);
-    method public static void setCustomSelectionActionModeCallback(android.widget.TextView, android.view.ActionMode.Callback);
-    method public static void setFirstBaselineToTopHeight(android.widget.TextView, @IntRange(from=0) @Px int);
-    method public static void setLastBaselineToBottomHeight(android.widget.TextView, @IntRange(from=0) @Px int);
-    method public static void setLineHeight(android.widget.TextView, @IntRange(from=0) @Px int);
-    method public static void setPrecomputedText(android.widget.TextView, androidx.core.text.PrecomputedTextCompat);
-    method public static void setTextAppearance(android.widget.TextView, @StyleRes int);
-    method public static void setTextMetricsParams(android.widget.TextView, androidx.core.text.PrecomputedTextCompat.Params);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.view.ActionMode.Callback? unwrapCustomSelectionActionModeCallback(android.view.ActionMode.Callback?);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static android.view.ActionMode.Callback? wrapCustomSelectionActionModeCallback(android.widget.TextView, android.view.ActionMode.Callback?);
-    field public static final int AUTO_SIZE_TEXT_TYPE_NONE = 0; // 0x0
-    field public static final int AUTO_SIZE_TEXT_TYPE_UNIFORM = 1; // 0x1
-  }
-
-  @IntDef({androidx.core.widget.TextViewCompat.AUTO_SIZE_TEXT_TYPE_NONE, androidx.core.widget.TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface TextViewCompat.AutoSizeTextType {
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class TextViewOnReceiveContentListener implements androidx.core.view.OnReceiveContentListener {
-    ctor public TextViewOnReceiveContentListener();
-    method public androidx.core.view.ContentInfoCompat? onReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface TintableCheckedTextView {
-    method public android.content.res.ColorStateList? getSupportCheckMarkTintList();
-    method public android.graphics.PorterDuff.Mode? getSupportCheckMarkTintMode();
-    method public void setSupportCheckMarkTintList(android.content.res.ColorStateList?);
-    method public void setSupportCheckMarkTintMode(android.graphics.PorterDuff.Mode?);
-  }
-
-  public interface TintableCompoundButton {
-    method public android.content.res.ColorStateList? getSupportButtonTintList();
-    method public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
-    method public void setSupportButtonTintList(android.content.res.ColorStateList?);
-    method public void setSupportButtonTintMode(android.graphics.PorterDuff.Mode?);
-  }
-
-  public interface TintableCompoundDrawablesView {
-    method public android.content.res.ColorStateList? getSupportCompoundDrawablesTintList();
-    method public android.graphics.PorterDuff.Mode? getSupportCompoundDrawablesTintMode();
-    method public void setSupportCompoundDrawablesTintList(android.content.res.ColorStateList?);
-    method public void setSupportCompoundDrawablesTintMode(android.graphics.PorterDuff.Mode?);
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface TintableImageSourceView {
-    method public android.content.res.ColorStateList? getSupportImageTintList();
-    method public android.graphics.PorterDuff.Mode? getSupportImageTintMode();
-    method public void setSupportImageTintList(android.content.res.ColorStateList?);
-    method public void setSupportImageTintMode(android.graphics.PorterDuff.Mode?);
-  }
-
-}
-
diff --git a/core/core/api/restricted_current.txt b/core/core/api/restricted_current.txt
index ec250b5..12ad90c 100644
--- a/core/core/api/restricted_current.txt
+++ b/core/core/api/restricted_current.txt
@@ -1118,10 +1118,15 @@
     method public static <T> T? getSystemService(android.content.Context, Class<T!>);
     method public static String? getSystemServiceName(android.content.Context, Class<?>);
     method public static boolean isDeviceProtectedStorage(android.content.Context);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, int);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, String?, android.os.Handler?, int);
     method public static boolean startActivities(android.content.Context, android.content.Intent![]);
     method public static boolean startActivities(android.content.Context, android.content.Intent![], android.os.Bundle?);
     method public static void startActivity(android.content.Context, android.content.Intent, android.os.Bundle?);
     method public static void startForegroundService(android.content.Context, android.content.Intent);
+    field public static final int RECEIVER_EXPORTED = 2; // 0x2
+    field public static final int RECEIVER_NOT_EXPORTED = 4; // 0x4
+    field public static final int RECEIVER_VISIBLE_TO_INSTANT_APPS = 1; // 0x1
   }
 
   public class FileProvider extends android.content.ContentProvider {
@@ -2069,6 +2074,7 @@
     method public java.util.Locale? getFirstMatch(String![]);
     method @IntRange(from=0xffffffff) public int indexOf(java.util.Locale?);
     method public boolean isEmpty();
+    method @RequiresApi(21) public static boolean matchesLanguageAndScript(java.util.Locale, java.util.Locale);
     method @IntRange(from=0) public int size();
     method public String toLanguageTags();
     method public Object? unwrap();
@@ -2087,7 +2093,18 @@
   }
 
   public final class ParcelCompat {
+    method public static <T> T![]? readArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> java.util.ArrayList<T!>? readArrayList(android.os.Parcel, ClassLoader?, Class<? extends T>);
     method public static boolean readBoolean(android.os.Parcel);
+    method public static <K, V> java.util.HashMap<K!,V!>? readHashMap(android.os.Parcel, ClassLoader?, Class<? extends K>, Class<? extends V>);
+    method public static <T> void readList(android.os.Parcel, java.util.List<? super T>, ClassLoader?, Class<T!>);
+    method public static <K, V> void readMap(android.os.Parcel, java.util.Map<? super K,? super V>, ClassLoader?, Class<K!>, Class<V!>);
+    method public static <T extends android.os.Parcelable> T? readParcelable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> T![]? readParcelableArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(30) public static <T> android.os.Parcelable.Creator<T!>? readParcelableCreator(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.Q) public static <T> java.util.List<T!> readParcelableList(android.os.Parcel, java.util.List<T!>, ClassLoader?, Class<T!>);
+    method public static <T extends java.io.Serializable> T? readSerializable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> android.util.SparseArray<T!>? readSparseArray(android.os.Parcel, ClassLoader?, Class<? extends T>);
     method public static void writeBoolean(android.os.Parcel, boolean);
   }
 
@@ -3478,6 +3495,9 @@
     method public static void setContentChangeTypes(android.view.accessibility.AccessibilityEvent, @androidx.core.view.accessibility.AccessibilityEventCompat.ContentChangeType int);
     method public static void setMovementGranularity(android.view.accessibility.AccessibilityEvent, int);
     field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_CANCELLED = 512; // 0x200
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_DROPPED = 256; // 0x100
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_STARTED = 128; // 0x80
     field public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 16; // 0x10
     field public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 32; // 0x20
     field public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 8; // 0x8
@@ -3506,7 +3526,7 @@
     field @Deprecated public static final int TYPE_WINDOW_CONTENT_CHANGED = 2048; // 0x800
   }
 
-  @IntDef(flag=true, value={androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_STATE_DESCRIPTION, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_SUBTREE, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_TEXT, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface AccessibilityEventCompat.ContentChangeType {
+  @IntDef(flag=true, value={androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_STATE_DESCRIPTION, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_SUBTREE, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_TEXT, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_DRAG_STARTED, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_DRAG_DROPPED, androidx.core.view.accessibility.AccessibilityEventCompat.CONTENT_CHANGE_TYPE_DRAG_CANCELLED}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface AccessibilityEventCompat.ContentChangeType {
   }
 
   public final class AccessibilityManagerCompat {
@@ -3579,6 +3599,7 @@
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat? getTouchDelegateInfo();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalAfter();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalBefore();
+    method public String? getUniqueId();
     method public String! getViewIdResourceName();
     method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat! getWindow();
     method public int getWindowId();
@@ -3672,6 +3693,7 @@
     method public void setTraversalAfter(android.view.View!, int);
     method public void setTraversalBefore(android.view.View!);
     method public void setTraversalBefore(android.view.View!, int);
+    method public void setUniqueId(String?);
     method public void setViewIdResourceName(String!);
     method public void setVisibleToUser(boolean);
     method public android.view.accessibility.AccessibilityNodeInfo! unwrap();
@@ -3737,6 +3759,9 @@
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COPY;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CUT;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_DISMISS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_CANCEL;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_DROP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_START;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_EXPAND;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_FOCUS;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_HIDE_TOOLTIP;
diff --git a/core/core/src/androidTest/java/androidx/core/app/ActivityCompatTest.java b/core/core/src/androidTest/java/androidx/core/app/ActivityCompatTest.java
index 9800531..3a5c843 100644
--- a/core/core/src/androidTest/java/androidx/core/app/ActivityCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/app/ActivityCompatTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertSame;
 import static org.mockito.AdditionalMatchers.aryEq;
 import static org.mockito.ArgumentMatchers.eq;
@@ -28,6 +29,7 @@
 
 import android.Manifest;
 import android.app.Activity;
+import android.os.Build;
 import android.support.v4.BaseInstrumentationTestCase;
 import android.view.View;
 
@@ -145,4 +147,12 @@
         ActivityCompat.requireViewById(getActivity(), View.NO_ID);
     }
 
+    @Test
+    public void testShouldShowRequestPermissionRationaleForPostNotifications() throws Throwable {
+        if (Build.VERSION.SDK_INT < 33) {
+            // permission doesn't exist yet, so should return false
+            assertFalse(ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
+                    Manifest.permission.POST_NOTIFICATIONS));
+        }
+    }
 }
diff --git a/core/core/src/androidTest/java/androidx/core/app/ComponentActivityTest.java b/core/core/src/androidTest/java/androidx/core/app/ComponentActivityTest.java
index 9d5b663..faf225c 100644
--- a/core/core/src/androidTest/java/androidx/core/app/ComponentActivityTest.java
+++ b/core/core/src/androidTest/java/androidx/core/app/ComponentActivityTest.java
@@ -90,6 +90,16 @@
         shouldNotDumpSpecialArgOnVersion("--translation", Build.VERSION_CODES.S);
     }
 
+    @Test
+    public void testShouldDumpInternalState_listDumpables() {
+        shouldNotDumpSpecialArgOnT("--list-dumpables");
+    }
+
+    @Test
+    public void testShouldDumpInternalState_dumpDumpable() {
+        shouldNotDumpSpecialArgOnT("--dump-dumpable");
+    }
+
     private void shouldNotDumpSpecialArgOnVersion(String specialArg, int minApiVersion) {
         String[] args = { specialArg };
         int actualApiVersion = Build.VERSION.SDK_INT;
@@ -103,6 +113,19 @@
         }
     }
 
+    private void shouldNotDumpSpecialArgOnT(String specialArg) {
+        String[] args = { specialArg };
+        int actualApiVersion = Build.VERSION.SDK_INT;
+
+        if (Build.VERSION.SDK_INT >= 33) {
+            assertFalse(specialArg + " should be skipped on API " + actualApiVersion,
+                    mComponentActivity.shouldDumpInternalState(args));
+        } else {
+            assertTrue(specialArg + " should be ignored on API " + actualApiVersion,
+                    mComponentActivity.shouldDumpInternalState(args));
+        }
+    }
+
     private class NeverAddedExtraData extends ComponentActivity.ExtraData {
     }
 
diff --git a/core/core/src/androidTest/java/androidx/core/app/JobIntentServiceTest.java b/core/core/src/androidTest/java/androidx/core/app/JobIntentServiceTest.java
index af95506..ed0ed4d 100644
--- a/core/core/src/androidTest/java/androidx/core/app/JobIntentServiceTest.java
+++ b/core/core/src/androidTest/java/androidx/core/app/JobIntentServiceTest.java
@@ -264,6 +264,7 @@
             Log.i(TAG, "Running!");
         }
 
+        @SuppressWarnings("deprecation")
         @Override
         protected void onHandleWork(@NonNull Intent intent) {
             Log.i(TAG, "Handling work: " + intent);
diff --git a/core/core/src/androidTest/java/androidx/core/app/ShareCompatTest.java b/core/core/src/androidTest/java/androidx/core/app/ShareCompatTest.java
index 0acf64e..90f0788 100644
--- a/core/core/src/androidTest/java/androidx/core/app/ShareCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/app/ShareCompatTest.java
@@ -38,7 +38,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-
+@SuppressWarnings("deprecation")
 @RunWith(AndroidJUnit4.class)
 @MediumTest
 public class ShareCompatTest extends BaseInstrumentationTestCase<TestActivity> {
@@ -54,6 +54,7 @@
         super(TestActivity.class);
     }
 
+    @SuppressWarnings("deprecation")
     @Test
     public void testBuilder() {
         Activity activity = mActivityTestRule.getActivity();
@@ -71,6 +72,7 @@
                 activity.getComponentName());
     }
 
+    @SuppressWarnings("deprecation")
     @Test
     public void testBuilderWithoutActivity() {
         Context context = mActivityTestRule.getActivity().getApplicationContext();
@@ -86,6 +88,7 @@
         assertNull(intent.getParcelableExtra(ShareCompat.EXTRA_CALLING_ACTIVITY_INTEROP));
     }
 
+    @SuppressWarnings("deprecation")
     @Test
     public void testBuilderWithWrappedActivity() {
         Activity activity = mActivityTestRule.getActivity();
@@ -104,6 +107,7 @@
                 activity.getComponentName());
     }
 
+    @SuppressWarnings("deprecation")
     @Test
     @SdkSuppress(minSdkVersion = 16)
     public void testBuilderSingleStreamUri() {
diff --git a/core/core/src/androidTest/java/androidx/core/content/ContextCompatTest.java b/core/core/src/androidTest/java/androidx/core/content/ContextCompatTest.java
index e55d822..1644add 100644
--- a/core/core/src/androidTest/java/androidx/core/content/ContextCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/content/ContextCompatTest.java
@@ -70,8 +70,14 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 
+import android.Manifest;
 import android.accounts.AccountManager;
 import android.app.ActivityManager;
 import android.app.AlarmManager;
@@ -87,12 +93,16 @@
 import android.app.usage.UsageStatsManager;
 import android.appwidget.AppWidgetManager;
 import android.bluetooth.BluetoothManager;
+import android.content.BroadcastReceiver;
 import android.content.ClipboardManager;
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.RestrictionsManager;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
 import android.content.res.ColorStateList;
 import android.graphics.drawable.Drawable;
 import android.hardware.ConsumerIrManager;
@@ -134,6 +144,7 @@
 import android.view.inputmethod.InputMethodManager;
 import android.view.textservice.TextServicesManager;
 
+import androidx.core.app.NotificationManagerCompat;
 import androidx.core.test.R;
 import androidx.test.filters.LargeTest;
 import androidx.test.filters.SdkSuppress;
@@ -146,7 +157,14 @@
 @LargeTest
 public class ContextCompatTest extends BaseInstrumentationTestCase<ThemedYellowActivity> {
     private Context mContext;
+    private IntentFilter mTestFilter = new IntentFilter();
+    private String mPermission;
+    private BroadcastReceiver mTestReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
 
+        }
+    };
     public ContextCompatTest() {
         super(ThemedYellowActivity.class);
     }
@@ -154,6 +172,7 @@
     @Before
     public void setup() {
         mContext = mActivityTestRule.getActivity();
+        mPermission = mContext.getPackageName() + ".DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION";
     }
 
     @Test
@@ -445,6 +464,86 @@
         return ((size * tdensity) + (sdensity >> 1)) / sdensity;
     }
 
+    @Test
+    public void testRegisterReceiver_noExportStateFlagThrowsException() {
+        assertThrows(IllegalArgumentException.class, () -> ContextCompat.registerReceiver(mContext,
+                mTestReceiver, mTestFilter, 0));
+
+        assertThrows(IllegalArgumentException.class, () -> ContextCompat.registerReceiver(mContext,
+                mTestReceiver, mTestFilter, Context.RECEIVER_VISIBLE_TO_INSTANT_APPS));
+    }
+
+    @Test
+    public void testRegisterReceiver_specifyBothExportStateFlagsThrowsException() {
+        assertThrows(IllegalArgumentException.class,
+                () -> ContextCompat.registerReceiver(mContext,
+                mTestReceiver, mTestFilter,
+                ContextCompat.RECEIVER_EXPORTED | ContextCompat.RECEIVER_NOT_EXPORTED));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 33)
+    public void testRegisterReceiverApi33() {
+        Context spyContext = spy(mContext);
+
+        ContextCompat.registerReceiver(spyContext, mTestReceiver, mTestFilter,
+                ContextCompat.RECEIVER_NOT_EXPORTED);
+        verify(spyContext).registerReceiver(eq(mTestReceiver), eq(mTestFilter), eq(null),
+                any(), eq(ContextCompat.RECEIVER_NOT_EXPORTED));
+
+        ContextCompat.registerReceiver(spyContext, mTestReceiver, mTestFilter,
+                ContextCompat.RECEIVER_EXPORTED);
+        verify(spyContext).registerReceiver(eq(mTestReceiver), eq(mTestFilter), eq(null), any(),
+                eq(ContextCompat.RECEIVER_EXPORTED));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 26, maxSdkVersion = 32)
+    public void testRegisterReceiverApi26() {
+        Context spyContext = spy(mContext);
+
+        ContextCompat.registerReceiver(spyContext, mTestReceiver, mTestFilter,
+                ContextCompat.RECEIVER_NOT_EXPORTED);
+        verify(spyContext).registerReceiver(eq(mTestReceiver), eq(mTestFilter),
+                eq(mPermission), any());
+
+        ContextCompat.registerReceiver(spyContext, mTestReceiver, mTestFilter,
+                ContextCompat.RECEIVER_EXPORTED);
+        verify(spyContext).registerReceiver(eq(mTestReceiver), eq(mTestFilter), eq(null), any(),
+                eq(0));
+
+    }
+
+    @Test
+    @SdkSuppress(maxSdkVersion = 25)
+    public void testRegisterReceiver() {
+        Context spyContext = spy(mContext);
+
+        ContextCompat.registerReceiver(spyContext, mTestReceiver, mTestFilter,
+                ContextCompat.RECEIVER_NOT_EXPORTED);
+        verify(spyContext).registerReceiver(eq(mTestReceiver), eq(mTestFilter), eq(mPermission),
+                any());
+
+        ContextCompat.registerReceiver(spyContext, mTestReceiver, mTestFilter,
+                ContextCompat.RECEIVER_EXPORTED);
+        verify(spyContext).registerReceiver(eq(mTestReceiver), eq(mTestFilter), eq(null), any());
+    }
+
+    @Test
+    public void testRegisterReceiver_mergedPermission_hasSignatureProtectionLevel()
+            throws Exception {
+        // Packages registering unexported runtime receivers on pre-T devices will have their
+        // receiver protected by a permission; to ensure other apps on the device cannot send a
+        // broadcast to these receivers, the permission must be declared with the signature
+        // protectionLevel.
+        PermissionInfo permissionInfo =
+                mContext.getPackageManager().getPermissionInfo(mPermission, 0);
+
+        assertEquals("The permission guarding unexported runtime receivers must have the "
+                + "signature protectionLevel.", PermissionInfo.PROTECTION_SIGNATURE,
+                permissionInfo.protectionLevel);
+    }
+
     @Test(expected = NullPointerException.class)
     public void testCheckSelfPermissionNull() {
         ContextCompat.checkSelfPermission(mContext, null);
@@ -474,4 +573,21 @@
                 ContextCompat.checkSelfPermission(mContext,
                         android.Manifest.permission.DELETE_PACKAGES));
     }
+
+    @Test
+    public void testCheckSelfPermissionNotificationPermission() {
+        if (Build.VERSION.SDK_INT >= 33) {
+            assertEquals(
+                    mContext.checkCallingPermission(Manifest.permission.POST_NOTIFICATIONS),
+                    ContextCompat.checkSelfPermission(
+                            mContext,
+                            Manifest.permission.POST_NOTIFICATIONS));
+        } else {
+            assertEquals("Notification permission allowed by default on devices <= SDK 32",
+                    NotificationManagerCompat.from(mContext).areNotificationsEnabled()
+                            ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED,
+                    ContextCompat.checkSelfPermission(mContext,
+                            Manifest.permission.POST_NOTIFICATIONS));
+        }
+    }
 }
diff --git a/core/core/src/androidTest/java/androidx/core/content/PackageManagerCompatTest.java b/core/core/src/androidTest/java/androidx/core/content/PackageManagerCompatTest.java
index 98a9aea..d612ba4 100644
--- a/core/core/src/androidTest/java/androidx/core/content/PackageManagerCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/content/PackageManagerCompatTest.java
@@ -318,6 +318,7 @@
      * this case, they are permission revocation apps.
      */
     @RequiresApi(api = Build.VERSION_CODES.KITKAT)
+    @SuppressWarnings("deprecation")
     static void setupPermissionRevocationApps(
             PackageManager packageManager, List<String> packageNames) {
         List<ResolveInfo> resolveInfos = new ArrayList<>();
diff --git a/core/core/src/androidTest/java/androidx/core/content/pm/PackageInfoCompatHasSignaturesTest.kt b/core/core/src/androidTest/java/androidx/core/content/pm/PackageInfoCompatHasSignaturesTest.kt
index 53f5500..bc98c5f 100644
--- a/core/core/src/androidTest/java/androidx/core/content/pm/PackageInfoCompatHasSignaturesTest.kt
+++ b/core/core/src/androidTest/java/androidx/core/content/pm/PackageInfoCompatHasSignaturesTest.kt
@@ -333,6 +333,7 @@
         }
     }
 
+    @Suppress("DEPRECATION")
     private fun mockPackageManager() = mockThrowOnUnmocked<PackageManager> {
         val mockCerts = params.mockCerts
         whenever(getPackageInfo(TEST_PKG_NAME, params.mockCerts.flag)) {
diff --git a/core/core/src/androidTest/java/androidx/core/content/pm/ShortcutManagerCompatTest.java b/core/core/src/androidTest/java/androidx/core/content/pm/ShortcutManagerCompatTest.java
index b4eb56a..6bab3ca 100644
--- a/core/core/src/androidTest/java/androidx/core/content/pm/ShortcutManagerCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/content/pm/ShortcutManagerCompatTest.java
@@ -89,7 +89,7 @@
 import java.util.Collections;
 import java.util.List;
 
-@SuppressWarnings("unchecked")
+@SuppressWarnings({"unchecked", "deprecation"})
 @RunWith(AndroidJUnit4.class)
 public class ShortcutManagerCompatTest extends BaseInstrumentationTestCase<TestActivity> {
 
diff --git a/core/core/src/androidTest/java/androidx/core/content/res/ResourcesCompatTest.java b/core/core/src/androidTest/java/androidx/core/content/res/ResourcesCompatTest.java
index 5d34169..dd7149b 100644
--- a/core/core/src/androidTest/java/androidx/core/content/res/ResourcesCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/content/res/ResourcesCompatTest.java
@@ -32,13 +32,12 @@
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.TransitionDrawable;
+import android.os.Build;
 import android.support.v4.testutils.TestUtils;
 import android.util.DisplayMetrics;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.OptIn;
 import androidx.core.graphics.TypefaceCompat;
-import androidx.core.os.BuildCompat;
 import androidx.core.provider.FontsContractCompat;
 import androidx.core.provider.MockFontProvider;
 import androidx.core.test.R;
@@ -526,7 +525,6 @@
         assertTrue(mutated instanceof TransitionDrawable);
     }
 
-    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
     @Test
     public void testClearCachesForTheme() {
         Resources.Theme theme = mResources.newTheme();
@@ -538,7 +536,7 @@
         ColorStateList csl2 = ResourcesCompat.getColorStateList(
                 mResources, R.color.color_state_list, theme);
 
-        if (!BuildCompat.isAtLeastT()) {
+        if (Build.VERSION.SDK_INT < 33) {
             // Validate the failure case that's being worked around.
             assertEquals(csl, csl2);
         } else {
diff --git a/core/core/src/androidTest/java/androidx/core/graphics/TypefaceCompatTest.java b/core/core/src/androidTest/java/androidx/core/graphics/TypefaceCompatTest.java
index 0ee4d9a..6efc56f 100644
--- a/core/core/src/androidTest/java/androidx/core/graphics/TypefaceCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/graphics/TypefaceCompatTest.java
@@ -59,6 +59,7 @@
 import java.util.concurrent.TimeUnit;
 
 @SmallTest
+@SuppressWarnings("deprecation")
 public class TypefaceCompatTest {
 
     public Context mContext;
diff --git a/core/core/src/androidTest/java/androidx/core/graphics/drawable/IconCompatTest.java b/core/core/src/androidTest/java/androidx/core/graphics/drawable/IconCompatTest.java
index 28d9898..60d3c11 100644
--- a/core/core/src/androidTest/java/androidx/core/graphics/drawable/IconCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/graphics/drawable/IconCompatTest.java
@@ -57,6 +57,7 @@
 import java.io.OutputStream;
 import java.util.Arrays;
 
+@SuppressWarnings("deprecation")
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class IconCompatTest {
diff --git a/core/core/src/androidTest/java/androidx/core/os/LocaleListCompatTest.java b/core/core/src/androidTest/java/androidx/core/os/LocaleListCompatTest.java
index 3fd5f6d..6bd9800 100644
--- a/core/core/src/androidTest/java/androidx/core/os/LocaleListCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/os/LocaleListCompatTest.java
@@ -393,6 +393,44 @@
         assertNotEquals(first.toLanguageTags(), second.toLanguageTags());
     }
 
+    @SdkSuppress(minSdkVersion = 21)
+    @Test
+    public void testLocaleListCompat_matchesLanguageAndScript() {
+        assertTrue(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("fr-Latn-FR"),
+                forLanguageTag("fr-Latn")));
+        assertTrue(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("zh-Hans-CN"),
+                forLanguageTag("zh-Hans")));
+        assertTrue(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("zh-Hant-TW"),
+                forLanguageTag("zh-Hant")));
+        assertTrue(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("en-US"),
+                forLanguageTag("en-US")));
+        assertTrue(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("en-US"),
+                forLanguageTag("en-CA")));
+        assertTrue(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("ar-NA"),
+                forLanguageTag("ar-ZA")));
+        assertTrue(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("zh-CN"),
+                forLanguageTag("zh")));
+        assertTrue(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("zh-CN"),
+                forLanguageTag("zh-Hans")));
+        assertTrue(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("zh-TW"),
+                forLanguageTag("zh-Hant")));
+
+        assertFalse(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("zh-Hant-TW"),
+                forLanguageTag("zh-Hans")));
+        assertFalse(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("en-XA"),
+                forLanguageTag("en-US")));
+        assertFalse(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("ar-YE"),
+                forLanguageTag("ar-XB")));
+        assertFalse(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("en-US"),
+                forLanguageTag("zh-TW")));
+        assertFalse(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("zh-TW"),
+                forLanguageTag("zh")));
+        assertFalse(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("zh-CN"),
+                forLanguageTag("zh-Hant")));
+        assertFalse(LocaleListCompat.matchesLanguageAndScript(forLanguageTag("zh-TW"),
+                forLanguageTag("zh-Hans")));
+    }
+
     private Locale forLanguageTag(String str) {
         if (Build.VERSION.SDK_INT >= 21) {
             return Locale.forLanguageTag(str);
diff --git a/core/core/src/androidTest/java/androidx/core/os/ParcelCompatTest.java b/core/core/src/androidTest/java/androidx/core/os/ParcelCompatTest.java
index e1d273b..873a9c2 100644
--- a/core/core/src/androidTest/java/androidx/core/os/ParcelCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/os/ParcelCompatTest.java
@@ -16,17 +16,31 @@
 
 package androidx.core.os;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
+import android.content.pm.Signature;
+import android.graphics.Rect;
+import android.os.Build;
 import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.SparseArray;
 
+import androidx.annotation.RequiresApi;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Objects;
+
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class ParcelCompatTest {
@@ -40,4 +54,186 @@
         assertTrue(ParcelCompat.readBoolean(p));
         assertFalse(ParcelCompat.readBoolean(p));
     }
+
+    @Test
+    public void readParcelable2Arg() {
+        Rect r = new Rect(0, 0, 10, 10);
+        Parcel p = Parcel.obtain();
+        p.writeParcelable(r, 0);
+
+        p.setDataPosition(0);
+        Rect r2 = ParcelCompat.readParcelable(p, Rect.class.getClassLoader(), Rect.class);
+        assertEquals(r, r2);
+    }
+
+    @Test
+    public void readArrayInT() {
+        Parcel p = Parcel.obtain();
+
+        Signature[] s = {new Signature("1234"),
+                null,
+                new Signature("abcd")};
+        p.writeArray(s);
+
+        p.setDataPosition(0);
+        Object[] objects = ParcelCompat.readArray(p, Signature.class.getClassLoader(),
+                Signature.class);
+        assertTrue(Arrays.equals(s, objects));
+        p.setDataPosition(0);
+
+        p.recycle();
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.S)
+    @Test
+    public void readSparseArrayInT() {
+        Parcel p = Parcel.obtain();
+
+        SparseArray<Signature> s = new SparseArray<>();
+        s.put(0, new Signature("1234567890abcdef"));
+        s.put(2, null);
+        s.put(3, new Signature("abcdef1234567890"));
+        p.writeSparseArray(s);
+
+        p.setDataPosition(0);
+        SparseArray<Signature> s1 = ParcelCompat.readSparseArray(p,
+                Signature.class.getClassLoader(), Signature.class);
+        assertEquals(s.size(), s1.size());
+        for (int index = 0; index < s.size(); index++) {
+            int key = s.keyAt(index);
+            assertTrue(Objects.equals(s.valueAt(index), s1.get(key)));
+        }
+
+        p.recycle();
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void readListInT() {
+        Parcel p = Parcel.obtain();
+        ArrayList<Signature> s = new ArrayList();
+        ArrayList<Signature> s2 = new ArrayList();
+        s.add(new Signature("1234567890abcdef"));
+        s.add(new Signature("abcdef1234567890"));
+
+        p.writeList(s);
+        p.setDataPosition(0);
+        ParcelCompat.readList(p, s2, Signature.class.getClassLoader(), Signature.class);
+        assertEquals(2, s2.size());
+        for (int i = 0; i < s2.size(); i++) {
+            assertEquals(s.get(i), s2.get(i));
+        }
+        p.recycle();
+    }
+
+    @Test
+    public void readArrayListInT() {
+        Parcel p = Parcel.obtain();
+
+        ArrayList<Signature> s = new ArrayList<>();
+        s.add(new Signature("1234567890abcdef"));
+        s.add(null);
+        s.add(new Signature("abcdef1234567890"));
+
+        p.writeList(s);
+        p.setDataPosition(0);
+        ArrayList<Signature> s1 = ParcelCompat.readArrayList(p, Signature.class.getClassLoader(),
+                Signature.class);
+        assertEquals(s, s1);
+
+        p.recycle();
+    }
+
+    @Test
+    public void readMapInT() {
+        Parcel p = Parcel.obtain();
+        ClassLoader loader = getClass().getClassLoader();
+        HashMap<String, Signature> map = new HashMap<>();
+        HashMap<String, Signature> map2 = new HashMap<>();
+
+        map.put("key1", new Signature("abcd"));
+        map.put("key2", new Signature("ABCD"));
+        p.writeMap(map);
+        p.setDataPosition(0);
+        ParcelCompat.readMap(p, map2, Signature.class.getClassLoader(), String.class,
+                Signature.class);
+        assertEquals(map, map2);
+
+        p.recycle();
+    }
+
+    @Test
+    public void readHashMapInT() {
+        Parcel p = Parcel.obtain();
+        ClassLoader loader = getClass().getClassLoader();
+        HashMap<String, Signature> map = new HashMap<>();
+        HashMap<String, Signature> map2 = new HashMap<>();
+
+        map.put("key1", new Signature("abcd"));
+        map.put("key2", new Signature("ABCD"));
+        p.writeMap(map);
+        p.setDataPosition(0);
+        map2 = ParcelCompat.readHashMap(p, loader, String.class, Signature.class);
+        assertEquals(map, map2);
+
+        p.recycle();
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.R)
+    @Test
+    public void readParcelableCreatorInT() {
+        final String signatureString  = "1234567890abcdef";
+        Signature s = new Signature(signatureString);
+
+        Parcel p = Parcel.obtain();
+        p.writeParcelableCreator(s);
+        p.setDataPosition(0);
+        assertSame(Signature.CREATOR, ParcelCompat.readParcelableCreator(p,
+                Signature.class.getClassLoader(), Signature.class));
+
+        p.setDataPosition(0);
+        p.recycle();
+    }
+
+    @Test
+    public void readParcelableArrayInT() {
+        Parcel p = Parcel.obtain();
+        Signature[] s = {new Signature("1234"),
+                null,
+                new Signature("abcd")
+        };
+        p.writeParcelableArray(s, 0);
+        p.setDataPosition(0);
+        Parcelable[] s1 = ParcelCompat.readParcelableArray(p, Signature.class.getClassLoader(),
+                Signature.class);
+        assertTrue(Arrays.equals(s, s1));
+        p.recycle();
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    @Test
+    public void readParcelableListInT() {
+        final Parcel p = Parcel.obtain();
+        ArrayList<Signature> list = new ArrayList<>();
+        ArrayList<Signature> list1 = new ArrayList<>();
+        list.add(new Signature("1234"));
+        list.add(new Signature("4321"));
+        p.writeParcelableList(list, 0);
+        p.setDataPosition(0);
+        ParcelCompat.readParcelableList(p, list1, Signature.class.getClassLoader(),
+                Signature.class);
+        assertEquals(list, list1);
+        p.recycle();
+    }
+
+    @Test
+    public void readSerializable2Arg() {
+        String s = "Hello World";
+        Parcel p = Parcel.obtain();
+        p.writeSerializable(s);
+
+        p.setDataPosition(0);
+        String s2 = ParcelCompat.readSerializable(p, String.class.getClassLoader(), String.class);
+        assertEquals(s, s2);
+    }
 }
diff --git a/core/core/src/androidTest/java/androidx/core/provider/FontsContractCompatTest.java b/core/core/src/androidTest/java/androidx/core/provider/FontsContractCompatTest.java
index 4499af4..5112fed 100644
--- a/core/core/src/androidTest/java/androidx/core/provider/FontsContractCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/provider/FontsContractCompatTest.java
@@ -68,6 +68,7 @@
  */
 @RunWith(AndroidJUnit4.class)
 @MediumTest
+@SuppressWarnings("deprecation")
 public class FontsContractCompatTest {
     private static final String AUTHORITY = "androidx.core.provider.fonts.font";
     private static final String PACKAGE = "androidx.core.test";
@@ -322,6 +323,7 @@
     }
 
     @Test
+    @SuppressWarnings("deprecation")
     public void testGetProvider_duplicateCerts()
             throws PackageManager.NameNotFoundException {
         PackageManager packageManager = mock(PackageManager.class);
@@ -377,6 +379,7 @@
         }
     }
 
+    @SuppressWarnings("deprecation")
     private ProviderInfo setupPackageManager(PackageManager packageManager)
             throws PackageManager.NameNotFoundException {
         ProviderInfo info = new ProviderInfo();
diff --git a/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java b/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
index e32d604..275e727 100644
--- a/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
@@ -125,6 +125,14 @@
         assertThat(nodeCompat.isTextEntryKey(), is(false));
     }
 
+    @Test
+    public void testGetSetUniqueId() {
+        final String uniqueId = (Build.VERSION.SDK_INT >= 19) ? "localUId" : null;
+        AccessibilityNodeInfoCompat nodeCompat = obtainedWrappedNodeCompat();
+        nodeCompat.setUniqueId(uniqueId);
+        assertThat(nodeCompat.getUniqueId(), equalTo(uniqueId));
+    }
+
     @SdkSuppress(minSdkVersion = 19)
     @Test
     public void testAccessibilityActionsNotNull() {
diff --git a/core/core/src/androidTest/java/androidx/core/widget/TextViewCompatTest.java b/core/core/src/androidTest/java/androidx/core/widget/TextViewCompatTest.java
index 2a9a40b..0765571 100644
--- a/core/core/src/androidTest/java/androidx/core/widget/TextViewCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/widget/TextViewCompatTest.java
@@ -489,6 +489,7 @@
 
     @Test
     @SdkSuppress(minSdkVersion = 26, maxSdkVersion =  27)
+    @SuppressWarnings("deprecation")
     public void testSetCustomSelectionActionModeCallback_fixesBugInO() {
         // Create mock context and package manager for the text view.
         final PackageManager packageManagerMock = spy(mTextView.getContext().getPackageManager());
diff --git a/core/core/src/main/AndroidManifest.xml b/core/core/src/main/AndroidManifest.xml
index 8481017..d214fa6 100644
--- a/core/core/src/main/AndroidManifest.xml
+++ b/core/core/src/main/AndroidManifest.xml
@@ -16,4 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
     <application
         android:appComponentFactory="androidx.core.app.CoreComponentFactory" />
+    <permission android:name="${applicationId}.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"
+        android:protectionLevel="signature" />
+    <uses-permission android:name="${applicationId}.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"/>
 </manifest>
diff --git a/core/core/src/main/java/androidx/core/app/ActivityCompat.java b/core/core/src/main/java/androidx/core/app/ActivityCompat.java
index 9cd1859..0f14ed5 100644
--- a/core/core/src/main/java/androidx/core/app/ActivityCompat.java
+++ b/core/core/src/main/java/androidx/core/app/ActivityCompat.java
@@ -16,6 +16,7 @@
 
 package androidx.core.app;
 
+import android.Manifest;
 import android.app.Activity;
 import android.content.Context;
 import android.content.ContextWrapper;
@@ -47,8 +48,10 @@
 import androidx.core.view.DragAndDropPermissionsCompat;
 
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Helper for accessing features in {@link android.app.Activity}.
@@ -331,6 +334,7 @@
      * <p>Note that this is <em>not</em> a security feature -- you can not trust the
      * referrer information, applications can spoof it.</p>
      */
+    @SuppressWarnings("deprecation")
     @Nullable
     public static Uri getReferrer(@NonNull Activity activity) {
         if (Build.VERSION.SDK_INT >= 22) {
@@ -486,6 +490,15 @@
      * RuntimePermissions</a> sample app demonstrates how to use this method to
      * request permissions at run time.
      * </p>
+     * <p>
+     * If {@link Manifest.permission#POST_NOTIFICATIONS} is requested before the device supports
+     * the notification permission, then {@link Manifest.permission#POST_NOTIFICATIONS} will be
+     * removed from {@link OnRequestPermissionsResultCallback#onRequestPermissionsResult}.
+     * For devices that don't support {@link Manifest.permission#POST_NOTIFICATIONS}, apps can
+     * send users to its notification settings to enable notifications. See
+     * {@link android.provider.Settings.ACTION_APP_NOTIFICATION_SETTINGS} for more information
+     * on launching notification settings.
+     * </p>
      *
      * @param activity The target activity.
      * @param permissions The requested permissions. Must be non-null and not empty.
@@ -505,11 +518,32 @@
             return;
         }
 
-        for (String permission : permissions) {
-            if (TextUtils.isEmpty(permission)) {
+        Set<Integer> indicesOfPermissionsToRemove = new HashSet<>();
+        for (int i = 0; i < permissions.length; i++) {
+            if (TextUtils.isEmpty(permissions[i])) {
                 throw new IllegalArgumentException("Permission request for permissions "
                         + Arrays.toString(permissions) + " must not contain null or empty values");
             }
+
+            if (Build.VERSION.SDK_INT < 33) {
+                if (TextUtils.equals(permissions[i], Manifest.permission.POST_NOTIFICATIONS)) {
+                    indicesOfPermissionsToRemove.add(i);
+                }
+            }
+        }
+
+        int numPermissionsToRemove = indicesOfPermissionsToRemove.size();
+        final String[] permissionsArray = numPermissionsToRemove > 0
+                ? new String[permissions.length - numPermissionsToRemove] : permissions;
+        if (numPermissionsToRemove > 0) {
+            if (numPermissionsToRemove == permissions.length) {
+                return;
+            }
+            for (int i = 0, modifiedIndex = 0; i < permissions.length; i++) {
+                if (!indicesOfPermissionsToRemove.contains(i)) {
+                    permissionsArray[modifiedIndex++] = permissions[i];
+                }
+            }
         }
 
         if (Build.VERSION.SDK_INT >= 23) {
@@ -523,19 +557,19 @@
             handler.post(new Runnable() {
                 @Override
                 public void run() {
-                    final int[] grantResults = new int[permissions.length];
+                    final int[] grantResults = new int[permissionsArray.length];
 
                     PackageManager packageManager = activity.getPackageManager();
                     String packageName = activity.getPackageName();
 
-                    final int permissionCount = permissions.length;
+                    final int permissionCount = permissionsArray.length;
                     for (int i = 0; i < permissionCount; i++) {
                         grantResults[i] = packageManager.checkPermission(
-                                permissions[i], packageName);
+                                permissionsArray[i], packageName);
                     }
 
                     ((OnRequestPermissionsResultCallback) activity).onRequestPermissionsResult(
-                            requestCode, permissions, grantResults);
+                            requestCode, permissionsArray, grantResults);
                 }
             });
         }
@@ -553,6 +587,11 @@
      */
     public static boolean shouldShowRequestPermissionRationale(@NonNull Activity activity,
             @NonNull String permission) {
+        if (Build.VERSION.SDK_INT < 33
+                && TextUtils.equals(Manifest.permission.POST_NOTIFICATIONS, permission)) {
+            // notification permission doesn't exist before T
+            return false;
+        }
         if (Build.VERSION.SDK_INT >= 23) {
             return Api23Impl.shouldShowRequestPermissionRationale(activity, permission);
         }
diff --git a/core/core/src/main/java/androidx/core/app/ComponentActivity.java b/core/core/src/main/java/androidx/core/app/ComponentActivity.java
index 764e041..dc8df10 100644
--- a/core/core/src/main/java/androidx/core/app/ComponentActivity.java
+++ b/core/core/src/main/java/androidx/core/app/ComponentActivity.java
@@ -177,6 +177,9 @@
                     return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
                 case "--translation":
                     return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
+                case "--list-dumpables":
+                case "--dump-dumpable":
+                    return Build.VERSION.SDK_INT >= 33;
             }
         }
         return false;
diff --git a/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java b/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
index de76c7f..08343a4 100644
--- a/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
@@ -794,6 +794,7 @@
          * Check the current list of enabled listener packages and update the records map
          * accordingly.
          */
+        @SuppressWarnings("deprecation")
         private void updateListenerMap() {
             Set<String> enabledPackages = getEnabledListenerPackages(mContext);
             if (enabledPackages.equals(mCachedEnabledPackages)) {
diff --git a/core/core/src/main/java/androidx/core/app/ShareCompat.java b/core/core/src/main/java/androidx/core/app/ShareCompat.java
index c209d4f..5cfe607 100644
--- a/core/core/src/main/java/androidx/core/app/ShareCompat.java
+++ b/core/core/src/main/java/androidx/core/app/ShareCompat.java
@@ -196,7 +196,7 @@
      * @param intent Intent that was launched to share content
      * @return ComponentName of the calling activity
      */
-    @SuppressWarnings("WeakerAccess")
+    @SuppressWarnings({"WeakerAccess", "deprecation"})
     @Nullable
     static ComponentName getCallingActivity(@NonNull Intent intent) {
         ComponentName result = intent.getParcelableExtra(EXTRA_CALLING_ACTIVITY);
@@ -882,6 +882,7 @@
          * @return A URI referring to a data stream to be shared or null if one was not supplied
          * @see Intent#EXTRA_STREAM
          */
+        @SuppressWarnings("deprecation")
         @Nullable
         public Uri getStream() {
             return mIntent.getParcelableExtra(Intent.EXTRA_STREAM);
@@ -896,6 +897,7 @@
          * @see Intent#EXTRA_STREAM
          * @see Intent#ACTION_SEND_MULTIPLE
          */
+        @SuppressWarnings("deprecation")
         @Nullable
         public Uri getStream(int index) {
             if (mStreams == null && isMultipleShare()) {
@@ -918,6 +920,7 @@
          *
          * @return Count of text items contained within the Intent
          */
+        @SuppressWarnings("deprecation")
         public int getStreamCount() {
             if (mStreams == null && isMultipleShare()) {
                 mStreams = mIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
@@ -1066,6 +1069,7 @@
          *
          * @return The calling application's label or null if unknown
          */
+        @SuppressWarnings("deprecation")
         @Nullable
         public CharSequence getCallingApplicationLabel() {
             if (mCallingPackage == null) return null;
diff --git a/core/core/src/main/java/androidx/core/content/ContextCompat.java b/core/core/src/main/java/androidx/core/content/ContextCompat.java
index 942112e..c6aa167 100644
--- a/core/core/src/main/java/androidx/core/content/ContextCompat.java
+++ b/core/core/src/main/java/androidx/core/content/ContextCompat.java
@@ -84,10 +84,12 @@
 import android.app.usage.UsageStatsManager;
 import android.appwidget.AppWidgetManager;
 import android.bluetooth.BluetoothManager;
+import android.content.BroadcastReceiver;
 import android.content.ClipboardManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.RestrictionsManager;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherApps;
@@ -126,6 +128,7 @@
 import android.telecom.TelecomManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.LayoutInflater;
@@ -139,16 +142,21 @@
 import androidx.annotation.ColorRes;
 import androidx.annotation.DoNotInline;
 import androidx.annotation.DrawableRes;
+import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
 import androidx.core.app.ActivityOptionsCompat;
+import androidx.core.app.NotificationManagerCompat;
 import androidx.core.content.res.ResourcesCompat;
 import androidx.core.os.EnvironmentCompat;
 import androidx.core.os.ExecutorCompat;
 import androidx.core.util.ObjectsCompat;
 
 import java.io.File;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.HashMap;
 import java.util.concurrent.Executor;
 
@@ -190,6 +198,35 @@
         return null;
     }
 
+
+    private static final String DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION_SUFFIX =
+            ".DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION";
+
+
+    /** @hide */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @IntDef(flag = true, value = {
+            RECEIVER_VISIBLE_TO_INSTANT_APPS, RECEIVER_EXPORTED, RECEIVER_NOT_EXPORTED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RegisterReceiverFlags {}
+    /**
+     * Flag for {@link #registerReceiver}: The receiver can receive broadcasts from Instant Apps.
+     */
+    public static final int RECEIVER_VISIBLE_TO_INSTANT_APPS = 0x1;
+
+    /**
+     * Flag for {@link #registerReceiver}: The receiver can receive broadcasts from other Apps.
+     * Has the same behavior as marking a statically registered receiver with "exported=true"
+     */
+    public static final int RECEIVER_EXPORTED = 0x2;
+
+    /**
+     * Flag for {@link #registerReceiver}: The receiver cannot receive broadcasts from other Apps.
+     * Has the same behavior as marking a statically registered receiver with "exported=false"
+     */
+    public static final int RECEIVER_NOT_EXPORTED = 0x4;
+
     /**
      * Start a set of activities as a synthesized task stack, if able.
      *
@@ -552,6 +589,12 @@
      */
     public static int checkSelfPermission(@NonNull Context context, @NonNull String permission) {
         ObjectsCompat.requireNonNull(permission, "permission must be non-null");
+        if (Build.VERSION.SDK_INT < 33
+                && TextUtils.equals(android.Manifest.permission.POST_NOTIFICATIONS, permission)) {
+            return NotificationManagerCompat.from(context).areNotificationsEnabled()
+                    ? PackageManager.PERMISSION_GRANTED
+                    : PackageManager.PERMISSION_DENIED;
+        }
         return context.checkPermission(permission, Process.myPid(), Process.myUid());
     }
 
@@ -727,6 +770,79 @@
     }
 
     /**
+     * Register a broadcast receiver.
+     *
+     * @param context  Context to retrieve service from.
+     * @param receiver The BroadcastReceiver to handle the broadcast.
+     * @param filter   Selects the Intent broadcasts to be received.
+     * @param flags    Specify one of {@link #RECEIVER_EXPORTED}, if you wish for your receiver
+     *                 to be able to receiver broadcasts from other applications, or
+     *                 {@link #RECEIVER_NOT_EXPORTED} if you only want your receiver to be able
+     *                 to receive broadcasts from the system or your own app.
+     * @return The first sticky intent found that matches <var>filter</var>,
+     * or null if there are none.
+     * @see Context#registerReceiver(BroadcastReceiver, IntentFilter, int)
+     */
+    @Nullable
+    public static Intent registerReceiver(@NonNull Context context,
+            @Nullable BroadcastReceiver receiver, @NonNull IntentFilter filter,
+            @RegisterReceiverFlags int flags) {
+        return registerReceiver(context, receiver, filter, null, null, flags);
+    }
+
+    /**
+     * Register a broadcast receiver.
+     *
+     * @param context             Context to retrieve service from.
+     * @param receiver            The BroadcastReceiver to handle the broadcast.
+     * @param filter              Selects the Intent broadcasts to be received.
+     * @param broadcastPermission String naming a permission that a broadcaster must hold in
+     *                            order to send and Intent to you. If null, no permission is
+     *                            required.
+     * @param scheduler           Handler identifying the thread will receive the Intent. If
+     *                            null, the main thread of the process will be used.
+     * @param flags               Specify one of {@link #RECEIVER_EXPORTED}, if you wish for your
+     *                            receiver to be able to receiver broadcasts from other
+     *                            applications, or {@link #RECEIVER_NOT_EXPORTED} if you only want
+     *                            your receiver to be able to receive broadcasts from the system
+     *                            or your own app.
+     * @return The first sticky intent found that matches <var>filter</var>,
+     * or null if there are none.
+     * @see Context#registerReceiver(BroadcastReceiver, IntentFilter, String, Handler, int)
+     */
+    @Nullable
+    public static Intent registerReceiver(@NonNull Context context,
+            @Nullable BroadcastReceiver receiver, @NonNull IntentFilter filter,
+            @Nullable String broadcastPermission,
+            @Nullable Handler scheduler, @RegisterReceiverFlags int flags) {
+        if (((flags & RECEIVER_EXPORTED) == 0) && ((flags & RECEIVER_NOT_EXPORTED) == 0)) {
+            throw new IllegalArgumentException("One of either RECEIVER_EXPORTED or "
+                    + "RECEIVER_NOT_EXPORTED is required");
+        }
+
+        if (((flags & RECEIVER_EXPORTED) != 0) && ((flags & RECEIVER_NOT_EXPORTED) != 0)) {
+            throw new IllegalArgumentException("Cannot specify both RECEIVER_EXPORTED and "
+                    + "RECEIVER_NOT_EXPORTED");
+        }
+
+        if (Build.VERSION.SDK_INT >= 33) {
+            return Api33Impl.registerReceiver(context, receiver, filter, broadcastPermission,
+                    scheduler, flags);
+        }
+        if (Build.VERSION.SDK_INT >= 26) {
+            return Api26Impl.registerReceiver(context, receiver, filter, broadcastPermission,
+                    scheduler, flags);
+        }
+        if (((flags & RECEIVER_NOT_EXPORTED) != 0) && (broadcastPermission == null)) {
+            String permission =
+                    context.getPackageName() + DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION_SUFFIX;
+            return context.registerReceiver(receiver, filter, permission, scheduler /* handler */);
+        }
+        return context.registerReceiver(receiver, filter, broadcastPermission,
+                scheduler);
+    }
+
+    /**
      * Gets the name of the system-level service that is represented by the specified class.
      *
      * @param context      Context to retrieve service name from.
@@ -925,6 +1041,19 @@
             // This class is not instantiable.
         }
 
+        @DoNotInline
+        static Intent registerReceiver(Context obj, @Nullable BroadcastReceiver receiver,
+                IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) {
+            if ((flags & RECEIVER_NOT_EXPORTED) != 0 && broadcastPermission == null) {
+                String permission =
+                        obj.getPackageName() + DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION_SUFFIX;
+                // receivers that are not exported should also not be visible to instant apps
+                return obj.registerReceiver(receiver, filter, permission, scheduler);
+            }
+            flags &= Context.RECEIVER_VISIBLE_TO_INSTANT_APPS;
+            return obj.registerReceiver(receiver, filter, broadcastPermission, scheduler, flags);
+        }
+
         @SuppressWarnings("UnusedReturnValue")
         @DoNotInline
         static ComponentName startForegroundService(Context obj, Intent service) {
@@ -955,4 +1084,17 @@
             return obj.getAttributionTag();
         }
     }
+
+    @RequiresApi(33)
+    static class Api33Impl {
+        private Api33Impl() {
+            // This class is not instantiable
+        }
+
+        @DoNotInline
+        static Intent registerReceiver(Context obj, @Nullable BroadcastReceiver receiver,
+                IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) {
+            return obj.registerReceiver(receiver, filter, broadcastPermission, scheduler, flags);
+        }
+    }
 }
diff --git a/core/core/src/main/java/androidx/core/content/PackageManagerCompat.java b/core/core/src/main/java/androidx/core/content/PackageManagerCompat.java
index 8831564..f932e1d 100644
--- a/core/core/src/main/java/androidx/core/content/PackageManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/content/PackageManagerCompat.java
@@ -217,6 +217,7 @@
      */
     @Nullable
     @RestrictTo(LIBRARY)
+    @SuppressWarnings("deprecation")
     public static String getPermissionRevocationVerifierApp(
             @NonNull PackageManager packageManager) {
         Intent permissionRevocationSettingsIntent =
diff --git a/core/core/src/main/java/androidx/core/content/pm/PackageInfoCompat.java b/core/core/src/main/java/androidx/core/content/pm/PackageInfoCompat.java
index 9a037c7..31372ce 100644
--- a/core/core/src/main/java/androidx/core/content/pm/PackageInfoCompat.java
+++ b/core/core/src/main/java/androidx/core/content/pm/PackageInfoCompat.java
@@ -81,6 +81,7 @@
      *                                              provided {@param packageManager}
      */
     @NonNull
+    @SuppressWarnings("deprecation")
     public static List<Signature> getSignatures(@NonNull PackageManager packageManager,
             @NonNull String packageName) throws PackageManager.NameNotFoundException {
         Signature[] array;
diff --git a/core/core/src/main/java/androidx/core/content/pm/ShortcutManagerCompat.java b/core/core/src/main/java/androidx/core/content/pm/ShortcutManagerCompat.java
index 33b02cb..169aba6 100644
--- a/core/core/src/main/java/androidx/core/content/pm/ShortcutManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/content/pm/ShortcutManagerCompat.java
@@ -860,6 +860,7 @@
         return sShortcutInfoCompatSaver;
     }
 
+    @SuppressWarnings("deprecation")
     private static List<ShortcutInfoChangeListener> getShortcutInfoListeners(Context context) {
         if (sShortcutInfoChangeListeners == null) {
             List<ShortcutInfoChangeListener> result = new ArrayList<>();
diff --git a/core/core/src/main/java/androidx/core/content/pm/ShortcutXmlParser.java b/core/core/src/main/java/androidx/core/content/pm/ShortcutXmlParser.java
index 95a9003..5b1e2ef 100644
--- a/core/core/src/main/java/androidx/core/content/pm/ShortcutXmlParser.java
+++ b/core/core/src/main/java/androidx/core/content/pm/ShortcutXmlParser.java
@@ -86,6 +86,7 @@
      * Returns a set of string which contains the ids of static shortcuts.
      */
     @NonNull
+    @SuppressWarnings("deprecation")
     private static Set<String> parseShortcutIds(@NonNull final Context context) {
         final Set<String> result = new HashSet<>();
         final Intent mainIntent = new Intent(Intent.ACTION_MAIN);
diff --git a/core/core/src/main/java/androidx/core/graphics/drawable/IconCompat.java b/core/core/src/main/java/androidx/core/graphics/drawable/IconCompat.java
index dd4b95a..8a8385c 100644
--- a/core/core/src/main/java/androidx/core/graphics/drawable/IconCompat.java
+++ b/core/core/src/main/java/androidx/core/graphics/drawable/IconCompat.java
@@ -682,6 +682,7 @@
         return null;
     }
 
+    @SuppressWarnings("deprecation")
     static Resources getResources(Context context, String resPackage) {
         if ("android".equals(resPackage)) {
             return Resources.getSystem();
diff --git a/core/core/src/main/java/androidx/core/net/ConnectivityManagerCompat.java b/core/core/src/main/java/androidx/core/net/ConnectivityManagerCompat.java
index 3c2c8f1..47c9dca 100644
--- a/core/core/src/main/java/androidx/core/net/ConnectivityManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/net/ConnectivityManagerCompat.java
@@ -137,6 +137,7 @@
      * potentially-stale value from
      * {@link ConnectivityManager#EXTRA_NETWORK_INFO}. May be {@code null}.
      */
+    @SuppressWarnings("deprecation")
     @SuppressLint("ReferencesDeprecated")
     @Nullable
     @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
diff --git a/core/core/src/main/java/androidx/core/os/BuildCompat.java b/core/core/src/main/java/androidx/core/os/BuildCompat.java
index 6e5a61f..80db0cd 100644
--- a/core/core/src/main/java/androidx/core/os/BuildCompat.java
+++ b/core/core/src/main/java/androidx/core/os/BuildCompat.java
@@ -68,7 +68,7 @@
      * @return {@code true} if N APIs are available for use
      * @deprecated Android N is a finalized release and this method is no longer necessary. It will
      *             be removed in a future release of the Support Library. Instead, use
-     *             {@code Build.VERSION.SDK_INT >= Build.VERSION_CODES.N}.
+     *             {@code Build.VERSION.SDK_INT >= 24}.
      */
     @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.N)
     @Deprecated
@@ -82,7 +82,7 @@
      * @return {@code true} if N MR1 APIs are available for use
      * @deprecated Android N MR1 is a finalized release and this method is no longer necessary. It
      *             will be removed in a future release of the Support Library. Instead, use
-     *             {@code Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1}.
+     *             {@code Build.VERSION.SDK_INT >= 25}.
      */
     @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.N_MR1)
     @Deprecated
@@ -96,7 +96,7 @@
      * @return {@code true} if O APIs are available for use, {@code false} otherwise
      * @deprecated Android O is a finalized release and this method is no longer necessary. It will
      *             be removed in a future release of the Support Library. Instead use
-     *             {@code Build.VERSION.SDK_INT >= Build.VERSION_CODES.O}.
+     *             {@code Build.VERSION.SDK_INT >= 26}.
      */
     @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.O)
     @Deprecated
@@ -110,7 +110,7 @@
      * @return {@code true} if O MR1 APIs are available for use, {@code false} otherwise
      * @deprecated Android O MR1 is a finalized release and this method is no longer necessary. It
      *             will be removed in a future release of the Support Library. Instead, use
-     *             {@code Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1}.
+     *             {@code Build.VERSION.SDK_INT >= 27}.
      */
     @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.O_MR1)
     @Deprecated
@@ -124,7 +124,7 @@
      * @return {@code true} if P APIs are available for use, {@code false} otherwise
      * @deprecated Android P is a finalized release and this method is no longer necessary. It
      *             will be removed in a future release of the Support Library. Instead, use
-     *             {@code Build.VERSION.SDK_INT >= Build.VERSION_CODES.P}.
+     *             {@code Build.VERSION.SDK_INT >= 28}.
      */
     @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.P)
     @Deprecated
@@ -138,7 +138,7 @@
      * @return {@code true} if Q APIs are available for use, {@code false} otherwise
      * @deprecated Android Q is a finalized release and this method is no longer necessary. It
      *             will be removed in a future release of the Support Library. Instead, use
-     *             {@code Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q}.
+     *             {@code Build.VERSION.SDK_INT >= 29}.
      */
     @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.Q)
     @Deprecated
@@ -152,7 +152,7 @@
      * @return {@code true} if R APIs are available for use, {@code false} otherwise
      * @deprecated Android R is a finalized release and this method is no longer necessary. It
      *             will be removed in a future release of the Support Library. Instead, use
-     *             {@code Build.VERSION.SDK_INT >= Build.VERSION_CODES.R}.
+     *             {@code Build.VERSION.SDK_INT >= 30}.
      */
     @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.R)
     @Deprecated
diff --git a/core/core/src/main/java/androidx/core/os/LocaleListCompat.java b/core/core/src/main/java/androidx/core/os/LocaleListCompat.java
index a09c8bf..f742a7e9 100644
--- a/core/core/src/main/java/androidx/core/os/LocaleListCompat.java
+++ b/core/core/src/main/java/androidx/core/os/LocaleListCompat.java
@@ -25,6 +25,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.Size;
+import androidx.core.text.ICUCompat;
 
 import java.util.Locale;
 
@@ -231,6 +232,86 @@
         }
     }
 
+    /**
+     * Determine whether two locales are considered a match, even if they are not exactly equal.
+     * They are considered as a match when both of their languages and scripts
+     * (explicit or inferred) are identical. This means that a user would be able to understand
+     * the content written in the supported locale even if they say they prefer the desired locale.
+     *
+     * E.g. [zh-HK] matches [zh-Hant]; [en-US] matches [en-CA].
+     *
+     * @param supported The supported {@link Locale} to be compared.
+     * @param desired   The desired {@link Locale} to be compared.
+     * @return True if they match, false otherwise.
+     */
+    @RequiresApi(21)
+    public static boolean matchesLanguageAndScript(@NonNull Locale supported,
+            @NonNull Locale desired) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return LocaleList.matchesLanguageAndScript(supported, desired);
+        } else if (Build.VERSION.SDK_INT >= 21) {
+            return Api21Impl.matchesLanguageAndScript(supported, desired);
+        } else {
+            throw new UnsupportedOperationException(
+                    "This method is only supported on API level 21+");
+        }
+    }
+
+    @RequiresApi(21)
+    static class Api21Impl {
+        private Api21Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static boolean matchesLanguageAndScript(@NonNull Locale supported,
+                @NonNull Locale desired) {
+            if (supported.equals(desired)) {
+                return true;  // return early so we don't do unnecessary computation
+            }
+            if (!supported.getLanguage().equals(desired.getLanguage())) {
+                return false;
+            }
+            if (isPseudoLocale(supported) || isPseudoLocale(desired)) {
+                // The locales are not the same, but the languages are the same, and one of the
+                // locales
+                // is a pseudo-locale. So this is not a match.
+                return false;
+            }
+            final String supportedScr = ICUCompat.maximizeAndGetScript(supported);
+            if (supportedScr.isEmpty()) {
+                // If we can't guess a script, we don't know enough about the locales' language
+                // to find
+                // if the locales match. So we fall back to old behavior of matching, which
+                // considered
+                // locales with different regions different.
+                final String supportedRegion = supported.getCountry();
+                return supportedRegion.isEmpty() || supportedRegion.equals(desired.getCountry());
+            }
+            final String desiredScr = ICUCompat.maximizeAndGetScript(desired);
+            // There is no match if the two locales use different scripts. This will most imporantly
+            // take care of traditional vs simplified Chinese.
+            return supportedScr.equals(desiredScr);
+        }
+
+        private static final Locale[] PSEUDO_LOCALE = {
+                new Locale("en", "XA"), new Locale("ar", "XB")};
+
+        private static boolean isPseudoLocale(Locale locale) {
+            for (Locale pseudoLocale : PSEUDO_LOCALE) {
+                if (pseudoLocale.equals(locale)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @DoNotInline
+        static Locale forLanguageTag(String languageTag) {
+            return Locale.forLanguageTag(languageTag);
+        }
+    }
+
     @Override
     public boolean equals(Object other) {
         return other instanceof LocaleListCompat && mImpl.equals(((LocaleListCompat) other).mImpl);
@@ -268,16 +349,4 @@
             return LocaleList.getDefault();
         }
     }
-
-    @RequiresApi(21)
-    static class Api21Impl {
-        private Api21Impl() {
-            // This class is not instantiable.
-        }
-
-        @DoNotInline
-        static Locale forLanguageTag(String languageTag) {
-            return Locale.forLanguageTag(languageTag);
-        }
-    }
 }
diff --git a/core/core/src/main/java/androidx/core/os/ParcelCompat.java b/core/core/src/main/java/androidx/core/os/ParcelCompat.java
index a181077..d43a904 100644
--- a/core/core/src/main/java/androidx/core/os/ParcelCompat.java
+++ b/core/core/src/main/java/androidx/core/os/ParcelCompat.java
@@ -16,9 +16,22 @@
 
 package androidx.core.os;
 
+import android.annotation.SuppressLint;
+import android.os.Build;
 import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.SparseArray;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * Helper for accessing features in {@link Parcel}.
@@ -43,5 +56,318 @@
         out.writeInt(value ? 1 : 0);
     }
 
+    /**
+     * Same as {@link Parcel#readList(List, ClassLoader)} but accepts {@code clazz} parameter as
+     * the type required for each item.
+     *
+     * @throws android.os.BadParcelableException Throws BadParcelableException if the item to be
+     * deserialized is not an instance of that class or any of its children classes or there was
+     * an error trying to instantiate an element.
+     */
+    @SuppressWarnings("deprecation")
+    public static <T> void readList(@NonNull Parcel in, @NonNull List<? super T> outVal,
+            @Nullable ClassLoader loader, @NonNull Class<T> clazz) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            TiramisuImpl.readList(in, outVal, loader, clazz);
+        } else {
+            in.readList(outVal, loader);
+        }
+    }
+
+    /**
+     * Same as {@link Parcel#readArrayList(ClassLoader)} but accepts {@code clazz} parameter as
+     * the type required for each item.
+     *
+     * @throws android.os.BadParcelableException Throws BadParcelableException if the item to be
+     * deserialized is not an instance of that class or any of its children classes or there was
+     * an error trying to instantiate an element.
+     */
+    @SuppressLint({"ConcreteCollection", "NullableCollection"})
+    @SuppressWarnings({"deprecation", "unchecked"})
+    @Nullable
+    public static <T> ArrayList<T> readArrayList(@NonNull Parcel in, @Nullable ClassLoader loader,
+            @NonNull Class<? extends T> clazz) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return TiramisuImpl.readArrayList(in, loader, clazz);
+        } else {
+            return in.readArrayList(loader);
+        }
+    }
+
+    /**
+     * Same as {@link Parcel#readArray(ClassLoader)} but accepts {@code clazz} parameter as
+     * the type required for each item.
+     *
+     * @throws android.os.BadParcelableException Throws BadParcelableException if the item to be
+     * deserialized is not an instance of that class or any of its children classes or there was
+     * an error trying to instantiate an element.
+     */
+    @SuppressWarnings({"deprecation", "unchecked"})
+    @SuppressLint({"ArrayReturn", "NullableCollection"})
+    @Nullable
+    public static <T> T[] readArray(@NonNull Parcel in, @Nullable ClassLoader loader,
+            @NonNull Class<T> clazz) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return TiramisuImpl.readArray(in, loader, clazz);
+        } else {
+            return (T[]) in.readArray(loader);
+        }
+    }
+
+    /**
+     * Same as {@link Parcel#readSparseArray(ClassLoader)} but accepts {@code clazz} parameter as
+     * the type required for each item.
+     *
+     * @throws android.os.BadParcelableException Throws BadParcelableException if the item to be
+     * deserialized is not an instance of that class or any of its children classes or there was
+     * an error trying to instantiate an element.
+     */
+    @SuppressWarnings("deprecation")
+    @Nullable
+    public static <T> SparseArray<T> readSparseArray(@NonNull Parcel in,
+            @Nullable ClassLoader loader,
+            @NonNull Class<? extends T> clazz) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return TiramisuImpl.readSparseArray(in, loader, clazz);
+        } else {
+            return in.readSparseArray(loader);
+        }
+    }
+
+
+    /**
+     * Same as {@link Parcel#readMap(Map, ClassLoader)} but accepts {@code clazzKey} and
+     * {@code clazzValue} parameter as the types required for each key and value pair.
+     *
+     * @throws android.os.BadParcelableException If the item to be deserialized is not an
+     * instance of that class or any of its children class.
+     */
+    @SuppressWarnings("deprecation")
+    public static <K, V> void readMap(@NonNull Parcel in, @NonNull Map<? super K, ? super V> outVal,
+            @Nullable ClassLoader loader, @NonNull Class<K> clazzKey,
+            @NonNull Class<V> clazzValue) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            TiramisuImpl.readMap(in, outVal, loader, clazzKey, clazzValue);
+        } else {
+            in.readMap(outVal, loader);
+        }
+    }
+
+    /**
+     * Same as {@link Parcel#readHashMap(ClassLoader)} but accepts {@code clazzKey} and
+     * {@code clazzValue} parameter as the types required for each key and value pair.
+     *
+     * @throws android.os.BadParcelableException if the item to be deserialized is not an
+     * instance of that class or any of its children class.
+     */
+    @SuppressLint({"ConcreteCollection", "NullableCollection"})
+    @SuppressWarnings({"deprecation", "unchecked"})
+    @Nullable
+    public static <K, V> HashMap<K, V> readHashMap(@NonNull Parcel in, @Nullable ClassLoader loader,
+            @NonNull Class<? extends K> clazzKey, @NonNull Class<? extends V> clazzValue) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return TiramisuImpl.readHashMap(in, loader, clazzKey, clazzValue);
+        } else {
+            return in.readHashMap(loader);
+        }
+    }
+
+    /**
+     * Same as {@link Parcel#readParcelable(ClassLoader)} but accepts {@code clazz} parameter as
+     * the type required for each item.
+     *
+     * @throws android.os.BadParcelableException Throws BadParcelableException if the item to be
+     * deserialized is not an instance of that class or any of its children classes or there was
+     * an error trying to instantiate an element.
+     */
+    @SuppressWarnings("deprecation")
+    @Nullable
+    public static <T extends Parcelable> T readParcelable(@NonNull Parcel in,
+            @Nullable ClassLoader loader, @NonNull Class<T> clazz) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return TiramisuImpl.readParcelable(in, loader, clazz);
+        } else {
+            return in.readParcelable(loader);
+        }
+    }
+
+    /**
+     * Same as {@link Parcel#readParcelableCreator(ClassLoader)} but accepts {@code clazz} parameter
+     * as the required type.
+     *
+     * @throws android.os.BadParcelableException Throws BadParcelableException if the item to be
+     * deserialized is not an instance of that class or any of its children classes or there
+     * there was an error trying to read the {@link Parcelable.Creator}.
+     */
+    @SuppressWarnings({"deprecation", "unchecked"})
+    @Nullable
+    @RequiresApi(30)
+    public static <T> Parcelable.Creator<T> readParcelableCreator(@NonNull Parcel in,
+            @Nullable ClassLoader loader, @NonNull Class<T> clazz) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return TiramisuImpl.readParcelableCreator(in, loader, clazz);
+        } else {
+            return (Parcelable.Creator<T>) Api30Impl.readParcelableCreator(in, loader);
+        }
+    }
+
+    /**
+     * Same as {@link Parcel#readParcelableArray(ClassLoader)}  but accepts {@code clazz} parameter
+     * as the type required for each item.
+     *
+     * @throws android.os.BadParcelableException Throws BadParcelableException if the item to be
+     * deserialized is not an instance of that class or any of its children classes or there was
+     * an error trying to instantiate an element.
+     */
+    @SuppressWarnings({"deprecation", "unchecked"})
+    @SuppressLint({"ArrayReturn", "NullableCollection"})
+    @Nullable
+    public static <T> T[] readParcelableArray(@NonNull Parcel in, @Nullable ClassLoader loader,
+            @NonNull Class<T> clazz) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return TiramisuImpl.readParcelableArray(in, loader, clazz);
+        } else {
+            return (T[]) in.readParcelableArray(loader);
+        }
+    }
+
+    /**
+     * Same as {@link Parcel#readParcelableList(List, ClassLoader)} but accepts {@code clazz}
+     * parameter as the type required for each item.
+     *
+     * @throws android.os.BadParcelableException Throws BadParcelableException if the item to be
+     * deserialized is not an instance of that class or any of its children classes or there was
+     * an error trying to instantiate an element.
+     */
+    @NonNull
+    @SuppressWarnings({"deprecation", "unchecked"})
+    @RequiresApi(api = Build.VERSION_CODES.Q)
+    public static <T> List<T> readParcelableList(@NonNull Parcel in, @NonNull List<T> list,
+            @Nullable ClassLoader cl, @NonNull Class<T> clazz) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return TiramisuImpl.readParcelableList(in, list, cl, clazz);
+        } else {
+            return Api29Impl.readParcelableList(in, (List) list, cl);
+        }
+    }
+
+    /**
+     * Same as {@link Parcel#readSerializable()} but accepts {@code loader} parameter
+     * as the primary classLoader for resolving the Serializable class; and {@code clazz} parameter
+     * as the required type.
+     *
+     * @throws android.os.BadParcelableException Throws BadParcelableException if the item to be
+     * deserialized is not an instance of that class or any of its children class or there there
+     * was an error deserializing the object.
+     */
+    @SuppressWarnings({"deprecation", "unchecked"})
+    @Nullable
+    public static <T extends Serializable> T readSerializable(@NonNull Parcel in,
+            @Nullable ClassLoader loader, @NonNull Class<T> clazz) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return TiramisuImpl.readSerializable(in, loader, clazz);
+        } else {
+            return (T) in.readSerializable();
+        }
+    }
+
     private ParcelCompat() {}
+
+    @RequiresApi(29)
+    static class Api29Impl {
+        private Api29Impl() {
+            // This class is non-instantiable.
+        }
+
+        @DoNotInline
+        static final <T extends Parcelable> List<T> readParcelableList(@NonNull Parcel in,
+                @NonNull List<T> list, @Nullable ClassLoader cl) {
+            return in.readParcelableList(list, cl);
+        }
+    }
+
+    @RequiresApi(30)
+    static class Api30Impl {
+        private Api30Impl() {
+            // This class is non-instantiable.
+        }
+
+        @DoNotInline
+        static final Parcelable.Creator<?> readParcelableCreator(@NonNull Parcel in,
+                @Nullable ClassLoader loader) {
+            return in.readParcelableCreator(loader);
+        }
+    }
+
+    @RequiresApi(33)
+    static class TiramisuImpl {
+        private TiramisuImpl() {
+            // This class is non-instantiable.
+        }
+
+        @DoNotInline
+        static <T extends Serializable> T readSerializable(@NonNull Parcel in,
+                @Nullable ClassLoader loader, @NonNull Class<T> clazz) {
+            return in.readSerializable(loader, clazz);
+        }
+
+        @DoNotInline
+        static <T extends Parcelable> T readParcelable(@NonNull Parcel in,
+                @Nullable ClassLoader loader, @NonNull Class<T> clazz) {
+            return in.readParcelable(loader, clazz);
+        }
+
+        @DoNotInline
+        public static <T> Parcelable.Creator<T> readParcelableCreator(Parcel in, ClassLoader loader,
+                Class<T> clazz) {
+            return in.readParcelableCreator(loader, clazz);
+        }
+
+        @DoNotInline
+        static <T> T[] readParcelableArray(@NonNull Parcel in, @Nullable ClassLoader loader,
+                @NonNull Class<T> clazz) {
+            return in.readParcelableArray(loader, clazz);
+        }
+
+        @DoNotInline
+        static <T> List<T> readParcelableList(@NonNull Parcel in, @NonNull List<T> list,
+                @Nullable ClassLoader cl, @NonNull Class<T> clazz) {
+            return in.readParcelableList(list, cl, clazz);
+        }
+
+        @DoNotInline
+        public static <T> void readList(@NonNull Parcel in, @NonNull List<? super T> outVal,
+                @Nullable ClassLoader loader, @NonNull Class<T> clazz) {
+            in.readList(outVal, loader, clazz);
+        }
+
+        @DoNotInline
+        public static <T> ArrayList<T> readArrayList(Parcel in, ClassLoader loader,
+                Class<? extends T> clazz) {
+            return in.readArrayList(loader, clazz);
+        }
+
+        @DoNotInline
+        public static <T> T[] readArray(Parcel in, ClassLoader loader, Class<T> clazz) {
+            return in.readArray(loader, clazz);
+        }
+
+        @DoNotInline
+        public static <T> SparseArray<T> readSparseArray(Parcel in, ClassLoader loader,
+                Class<? extends T> clazz) {
+            return in.readSparseArray(loader, clazz);
+        }
+
+        @DoNotInline
+        public static <K, V> void readMap(Parcel in, Map<? super K, ? super V> outVal,
+                ClassLoader loader, Class<K> clazzKey, Class<V> clazzValue) {
+            in.readMap(outVal, loader, clazzKey, clazzValue);
+        }
+
+        @DoNotInline
+        public static <V, K> HashMap<K, V> readHashMap(Parcel in, ClassLoader loader,
+                Class<? extends K> clazzKey, Class<? extends V> clazzValue) {
+            return in.readHashMap(loader, clazzKey, clazzValue);
+        }
+    }
 }
diff --git a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityEventCompat.java b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityEventCompat.java
index ed6beeb..74a0ae7 100644
--- a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityEventCompat.java
+++ b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityEventCompat.java
@@ -202,6 +202,36 @@
     public static final int CONTENT_CHANGE_TYPE_STATE_DESCRIPTION = 0x00000040;
 
     /**
+     * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
+     * A drag has started while accessibility is enabled. This is either via an
+     * AccessibilityAction, or via touch events. This is sent from the source that initiated the
+     * drag.
+     *
+     * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_DRAG_START
+     */
+    public static final int CONTENT_CHANGE_TYPE_DRAG_STARTED = 0x00000080;
+
+    /**
+     * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
+     * A drag in with accessibility enabled has ended. This means the content has been
+     * successfully dropped. This is sent from the target that accepted the dragged content.
+     *
+     * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_DRAG_DROP
+     */
+    public static final int CONTENT_CHANGE_TYPE_DRAG_DROPPED = 0x00000100;
+
+    /**
+     * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
+     * A drag in with accessibility enabled has ended. This means the content has been
+     * unsuccessfully dropped, the user has canceled the action via an AccessibilityAction, or
+     * no drop has been detected within a timeout and the drag was automatically cancelled. This is
+     * sent from the source that initiated the drag.
+     *
+     * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_DRAG_CANCEL
+     */
+    public static final int CONTENT_CHANGE_TYPE_DRAG_CANCELLED = 0x0000200;
+
+    /**
      * Mask for {@link AccessibilityEvent} all types.
      *
      * @see AccessibilityEvent#TYPE_VIEW_CLICKED
@@ -238,7 +268,10 @@
                     CONTENT_CHANGE_TYPE_STATE_DESCRIPTION,
                     CONTENT_CHANGE_TYPE_SUBTREE,
                     CONTENT_CHANGE_TYPE_TEXT,
-                    CONTENT_CHANGE_TYPE_UNDEFINED
+                    CONTENT_CHANGE_TYPE_UNDEFINED,
+                    CONTENT_CHANGE_TYPE_DRAG_STARTED,
+                    CONTENT_CHANGE_TYPE_DRAG_DROPPED,
+                    CONTENT_CHANGE_TYPE_DRAG_CANCELLED
             })
     @RestrictTo(LIBRARY_GROUP_PREFIX)
     @Retention(RetentionPolicy.SOURCE)
diff --git a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
index 446b6dc..7fdab07 100644
--- a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
+++ b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
@@ -23,6 +23,7 @@
 import static java.util.Collections.emptyList;
 
 import android.annotation.SuppressLint;
+import android.content.ClipData;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Build;
@@ -45,7 +46,6 @@
 import androidx.annotation.RestrictTo;
 import androidx.core.R;
 import androidx.core.accessibilityservice.AccessibilityServiceInfoCompat;
-import androidx.core.os.BuildCompat;
 import androidx.core.view.ViewCompat;
 import androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments;
 import androidx.core.view.accessibility.AccessibilityViewCommand.MoveAtGranularityArguments;
@@ -591,6 +591,54 @@
                         ? AccessibilityNodeInfo.AccessibilityAction.ACTION_IME_ENTER : null,
                         android.R.id.accessibilityActionImeEnter, null, null, null);
 
+        /**
+         * Action to start a drag.
+         * <p>
+         * This action initiates a drag & drop within the system. The source's dragged content is
+         * prepared before the drag begins. In View, this action should prepare the arguments to
+         * {@link View#startDragAndDrop(ClipData, View.DragShadowBuilder, Object, int)}} and then
+         * call the method. The equivalent should be performed for other UI toolkits.
+         * </p>
+         *
+         * @see AccessibilityEventCompat#CONTENT_CHANGE_TYPE_DRAG_STARTED
+         */
+        @NonNull
+        public static final AccessibilityActionCompat ACTION_DRAG_START =
+                new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 32
+                        ?  AccessibilityNodeInfo.AccessibilityAction.ACTION_DRAG_START : null,
+                        android.R.id.accessibilityActionDragStart, null, null, null);
+
+        /**
+         * Action to trigger a drop of the content being dragged.
+         * <p>
+         * This action is added to potential drop targets if the source started a drag with
+         * {@link #ACTION_DRAG_START}. In View, these targets are Views that accepted
+         * {@link android.view.DragEvent#ACTION_DRAG_STARTED} and have an
+         * {@link View.OnDragListener}.
+         * </p>
+         *
+         * @see AccessibilityEventCompat#CONTENT_CHANGE_TYPE_DRAG_DROPPED
+         */
+        @NonNull
+        public static final AccessibilityActionCompat ACTION_DRAG_DROP =
+                new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 32
+                        ?  AccessibilityNodeInfo.AccessibilityAction.ACTION_DRAG_DROP : null,
+                        android.R.id.accessibilityActionDragDrop, null, null, null);
+
+        /**
+         * Action to cancel a drag.
+         * <p>
+         * This action is added to the source that started a drag with {@link #ACTION_DRAG_START}.
+         * </p>
+         *
+         * @see AccessibilityEventCompat#CONTENT_CHANGE_TYPE_DRAG_CANCELLED
+         */
+        @NonNull
+        public static final AccessibilityActionCompat ACTION_DRAG_CANCEL =
+                new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 32
+                        ?  AccessibilityNodeInfo.AccessibilityAction.ACTION_DRAG_CANCEL : null,
+                        android.R.id.accessibilityActionDragCancel, null, null, null);
+
         final Object mAction;
         private final int mId;
         private final Class<? extends CommandArguments> mViewCommandArgumentClass;
@@ -1235,6 +1283,9 @@
     private static final String STATE_DESCRIPTION_KEY =
             "androidx.view.accessibility.AccessibilityNodeInfoCompat.STATE_DESCRIPTION_KEY";
 
+    private static final String UNIQUE_ID_KEY =
+            "androidx.view.accessibility.AccessibilityNodeInfoCompat.UNIQUE_ID_KEY";
+
     // These don't line up with the internal framework constants, since they are independent
     // and we might as well get all 32 bits of utility here.
     private static final int BOOLEAN_PROPERTY_SCREEN_READER_FOCUSABLE = 0x00000001;
@@ -2811,7 +2862,7 @@
      * than 19.
      */
     public @Nullable CharSequence getStateDescription() {
-        if (BuildCompat.isAtLeastR()) {
+        if (Build.VERSION.SDK_INT >= 30) {
             return mInfo.getStateDescription();
         } else if (Build.VERSION.SDK_INT >= 19) {
             return mInfo.getExtras().getCharSequence(STATE_DESCRIPTION_KEY);
@@ -2846,7 +2897,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setStateDescription(@Nullable CharSequence stateDescription) {
-        if (BuildCompat.isAtLeastR()) {
+        if (Build.VERSION.SDK_INT >= 30) {
             mInfo.setStateDescription(stateDescription);
         } else if (Build.VERSION.SDK_INT >= 19) {
             mInfo.getExtras().putCharSequence(STATE_DESCRIPTION_KEY, stateDescription);
@@ -2854,6 +2905,40 @@
     }
 
     /**
+     * Gets the unique id of this node.
+     *
+     * @return the unique id or null if android version smaller
+     * than 19.
+     */
+    public @Nullable String getUniqueId() {
+        if (Build.VERSION.SDK_INT >= 33) {
+            return mInfo.getUniqueId();
+        } else if (Build.VERSION.SDK_INT >= 19) {
+            return mInfo.getExtras().getString(UNIQUE_ID_KEY);
+        }
+        return null;
+    }
+
+    /**
+     * Sets the unique id of this node.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param uniqueId the unique id of this node.
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    public void setUniqueId(@Nullable String uniqueId) {
+        if (Build.VERSION.SDK_INT >= 33) {
+            mInfo.setUniqueId(uniqueId);
+        } else if (Build.VERSION.SDK_INT >= 19) {
+            mInfo.getExtras().putString(UNIQUE_ID_KEY, uniqueId);
+        }
+    }
+
+    /**
      * Return an instance back to be reused.
      * <p>
      * <strong>Note:</strong> You must not touch the object after calling this function.
@@ -4031,7 +4116,7 @@
      */
     public @Nullable CharSequence getRoleDescription() {
         if (Build.VERSION.SDK_INT >= 19) {
-            return mInfo.getExtras().getCharSequence(ROLE_DESCRIPTION_KEY);
+            return getExtras().getCharSequence(ROLE_DESCRIPTION_KEY);
         } else {
             return null;
         }
@@ -4063,7 +4148,7 @@
      */
     public void setRoleDescription(@Nullable CharSequence roleDescription) {
         if (Build.VERSION.SDK_INT >= 19) {
-            mInfo.getExtras().putCharSequence(ROLE_DESCRIPTION_KEY, roleDescription);
+            getExtras().putCharSequence(ROLE_DESCRIPTION_KEY, roleDescription);
         }
     }
 
@@ -4169,6 +4254,7 @@
         builder.append("; text: ").append(getText());
         builder.append("; contentDescription: ").append(getContentDescription());
         builder.append("; viewId: ").append(getViewIdResourceName());
+        builder.append("; uniqueId: ").append(getUniqueId());
 
         builder.append("; checkable: ").append(isCheckable());
         builder.append("; checked: ").append(isChecked());
@@ -4304,8 +4390,14 @@
                 return "ACTION_PRESS_AND_HOLD";
             case android.R.id.accessibilityActionImeEnter:
                 return "ACTION_IME_ENTER";
+            case android.R.id.accessibilityActionDragStart:
+                return "ACTION_DRAG_START";
+            case android.R.id.accessibilityActionDragDrop:
+                return "ACTION_DRAG_DROP";
+            case android.R.id.accessibilityActionDragCancel:
+                return "ACTION_DRAG_CANCEL";
             default:
-                return"ACTION_UNKNOWN";
+                return "ACTION_UNKNOWN";
         }
     }
 }
diff --git a/core/core/src/main/java/androidx/core/widget/TextViewCompat.java b/core/core/src/main/java/androidx/core/widget/TextViewCompat.java
index 7a6a655..dfb25e3 100644
--- a/core/core/src/main/java/androidx/core/widget/TextViewCompat.java
+++ b/core/core/src/main/java/androidx/core/widget/TextViewCompat.java
@@ -650,6 +650,7 @@
             }
         }
 
+        @SuppressWarnings("deprecation")
         private List<ResolveInfo> getSupportedActivities(final Context context,
                 final PackageManager packageManager) {
             final List<ResolveInfo> supportedActivities = new ArrayList<>();
diff --git a/development/studio/idea.properties b/development/studio/idea.properties
index fd64fdb..bd80f7b 100644
--- a/development/studio/idea.properties
+++ b/development/studio/idea.properties
@@ -5,12 +5,12 @@
 #---------------------------------------------------------------------
 # Uncomment this option if you want to customize path to IDE config folder. Make sure you're using forward slashes.
 #---------------------------------------------------------------------
-idea.config.path=${user.home}/.AndroidStudioAndroidX/config
+idea.config.path=${user.home}/.AndroidStudioAndroidXPlatform/config
 
 #---------------------------------------------------------------------
 # Uncomment this option if you want to customize path to IDE system folder. Make sure you're using forward slashes.
 #---------------------------------------------------------------------
-idea.system.path=${user.home}/.AndroidStudioAndroidX/system
+idea.system.path=${user.home}/.AndroidStudioAndroidXPlatform/system
 
 #---------------------------------------------------------------------
 # Uncomment this option if you want to customize path to user installed plugins folder. Make sure you're using forward slashes.
diff --git a/docs-public/build.gradle b/docs-public/build.gradle
index 5d1050e..435c4b5 100644
--- a/docs-public/build.gradle
+++ b/docs-public/build.gradle
@@ -4,16 +4,16 @@
 }
 
 dependencies {
-    docs("androidx.activity:activity:1.5.0-rc01")
-    docs("androidx.activity:activity-compose:1.5.0-rc01")
-    samples("androidx.activity:activity-compose-samples:1.5.0-rc01")
-    docs("androidx.activity:activity-ktx:1.5.0-rc01")
+    docs("androidx.activity:activity:1.6.0-alpha03")
+    docs("androidx.activity:activity-compose:1.6.0-alpha03")
+    samples("androidx.activity:activity-compose-samples:1.6.0-alpha03")
+    docs("androidx.activity:activity-ktx:1.6.0-alpha03")
     docs("androidx.ads:ads-identifier:1.0.0-alpha04")
     docs("androidx.ads:ads-identifier-provider:1.0.0-alpha04")
     docs("androidx.annotation:annotation:1.4.0-alpha02")
     docs("androidx.annotation:annotation-experimental:1.2.0")
-    docs("androidx.appcompat:appcompat:1.5.0-alpha01")
-    docs("androidx.appcompat:appcompat-resources:1.5.0-alpha01")
+    docs("androidx.appcompat:appcompat:1.6.0-alpha03")
+    docs("androidx.appcompat:appcompat-resources:1.6.0-alpha03")
     docs("androidx.appsearch:appsearch:1.0.0-alpha04")
     docs("androidx.appsearch:appsearch-ktx:1.0.0-alpha04")
     docs("androidx.appsearch:appsearch-local-storage:1.0.0-alpha04")
@@ -105,8 +105,8 @@
     docs("androidx.core:core-role:1.1.0-rc01")
     docs("androidx.core:core-animation:1.0.0-beta01")
     docs("androidx.core:core-animation-testing:1.0.0-alpha02")
-    docs("androidx.core:core:1.8.0-rc01")
-    docs("androidx.core:core-ktx:1.8.0-rc01")
+    docs("androidx.core:core:1.9.0-alpha03")
+    docs("androidx.core:core-ktx:1.9.0-alpha03")
     docs("androidx.core:core-splashscreen:1.0.0-beta02")
     docs("androidx.cursoradapter:cursoradapter:1.0.0")
     docs("androidx.customview:customview:1.2.0-alpha01")
diff --git a/docs-tip-of-tree/build.gradle b/docs-tip-of-tree/build.gradle
index c187e5f..53ec31f 100644
--- a/docs-tip-of-tree/build.gradle
+++ b/docs-tip-of-tree/build.gradle
@@ -148,6 +148,7 @@
     docs(project(":glance:glance"))
     docs(project(":glance:glance-appwidget"))
     docs(project(":glance:glance-wear-tiles"))
+    docs(project(":graphics:graphics-core"))
     docs(project(":gridlayout:gridlayout"))
     docs(project(":health:health-connect-client"))
     docs(project(":health:health-services-client"))
diff --git a/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/FlingTests.java b/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/FlingTests.java
index 75f6869..0933984 100644
--- a/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/FlingTests.java
+++ b/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/FlingTests.java
@@ -149,6 +149,9 @@
             @Override
             public void run() {
                 animHighFriction.setStartVelocity(5000).setStartValue(0).start();
+                // Set the duration scale to 1 to avoid prematurely ending the animation.
+                // ValueAnimator#getDurationScale is called in start().
+                animHighFriction.getAnimationHandler().mDurationScale = 1.0f;
                 animLowFriction.setStartVelocity(5000).setStartValue(0).start();
             }
         });
@@ -201,6 +204,8 @@
             @Override
             public void run() {
                 animHighThreshold.setStartVelocity(2000).setStartValue(0).start();
+                // Set the duration scale to 1 to avoid prematurely ending the animation.
+                animHighThreshold.getAnimationHandler().mDurationScale = 1.0f;
                 animLowThreshold.setStartVelocity(2000).setStartValue(0).start();
             }
         });
diff --git a/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java b/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
index c6fff9a..d77c4b1 100644
--- a/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
+++ b/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.AdditionalMatchers.lt;
@@ -38,7 +39,9 @@
 import android.view.View;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
 import androidx.core.view.ViewCompat;
+import androidx.dynamicanimation.animation.AnimationHandler;
 import androidx.dynamicanimation.animation.DynamicAnimation;
 import androidx.dynamicanimation.animation.FloatPropertyCompat;
 import androidx.dynamicanimation.animation.FloatValueHolder;
@@ -151,6 +154,9 @@
             @Override
             public void run() {
                 anim.setStartValue(0).start();
+                // Set the duration scale to 1 to avoid prematurely ending the animation.
+                // ValueAnimator#getDurationScale is called in start().
+                anim.getAnimationHandler().mDurationScale = 1.0f;
             }
         });
 
@@ -247,10 +253,14 @@
             public void run() {
                 anim2.setStartValue(800).addUpdateListener(updateListener).addEndListener(l2)
                         .start();
+                // Set the duration scale to 1 to avoid prematurely ending the animation.
+                anim2.getAnimationHandler().mDurationScale = 1.0f;
                 anim3.setStartValue(800).addUpdateListener(updateListener).addEndListener(l3)
                         .addEndListener(mockListener).start();
+                anim3.getAnimationHandler().mDurationScale = 1.0f;
                 anim1.setStartValue(800).addUpdateListener(updateListener).addEndListener(l1)
                         .start();
+                anim1.getAnimationHandler().mDurationScale = 1.0f;
 
             }
         });
@@ -311,9 +321,13 @@
             public void run() {
                 anim1.setStartValue(360).addUpdateListener(updateListener).addEndListener(l1)
                         .start();
+                // Set the duration scale to 1 to avoid prematurely ending the animation.
+                anim1.getAnimationHandler().mDurationScale = 1.0f;
                 anim2.setStartValue(360).addUpdateListener(updateListener).addEndListener(l2)
                         .addEndListener(mockListener).start();
+                anim2.getAnimationHandler().mDurationScale = 1.0f;
                 anim3.setStartValue(360).addEndListener(l3).start();
+                anim3.getAnimationHandler().mDurationScale = 1.0f;
             }
         });
         // The spring animation with critically-damped spring should return to rest position faster.
@@ -374,6 +388,8 @@
                 public void run() {
                     for (int j = 0; j < stiffness.length; j++) {
                         springAnims[j].start();
+                        // Set the duration scale to 1 to avoid prematurely ending the animation.
+                        springAnims[j].getAnimationHandler().mDurationScale = 1.0f;
                     }
                 }
             });
@@ -530,6 +546,8 @@
             @Override
             public void run() {
                 anim.animateToFinalPosition(0.0f);
+                // Set the duration scale to 1 to avoid prematurely ending the animation.
+                anim.getAnimationHandler().mDurationScale = 1.0f;
             }
         });
         assertTrue(anim.isRunning());
@@ -539,6 +557,8 @@
             @Override
             public void run() {
                 anim.animateToFinalPosition(1.0f);
+                // Set the duration scale to 1 to avoid prematurely ending the animation.
+                anim.getAnimationHandler().mDurationScale = 1.0f;
             }
         });
 
@@ -855,6 +875,41 @@
     }
 
     @Test
+    @RequiresApi(api = 33)
+    public void testDurationScaleChangeListener() throws InterruptedException {
+        final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.Y, 0f);
+        final CountDownLatch registerUnregisterLatch = new CountDownLatch(2);
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                // getAnimationHandler and AnimationHandler.getInstance() requires a looper, so run
+                // on the main thread.
+                AnimationHandler animHandler = anim.getAnimationHandler();
+                assertEquals(1, animHandler.getDurationScale(), 0);
+                assertNull(animHandler.mDurationScaleChangeListener);
+                animHandler.mDurationScaleChangeListener =
+                        new MyDurationScaleChangeListener(animHandler, registerUnregisterLatch);
+
+                anim.start();
+                assertEquals(0, animHandler.getDurationScale(), 0);
+            }
+        });
+
+        // Wait for the animation to end on the main thread.
+        assertTrue(registerUnregisterLatch.await(1000, TimeUnit.MILLISECONDS));
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                AnimationHandler animHandler = anim.getAnimationHandler();
+                // Remove our custom listener at the end.
+                animHandler.mDurationScaleChangeListener = null;
+            }
+        });
+    }
+
+    @Test
     public void testCustomHandler() {
         final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.Y, 0f);
         MyAnimationFrameCallbackScheduler scheduler =
@@ -897,4 +952,29 @@
             endTime = SystemClock.uptimeMillis();
         }
     }
+
+    @RequiresApi(api = 33)
+    class MyDurationScaleChangeListener extends AnimationHandler.DurationScaleChangeListener33 {
+
+        final CountDownLatch mRegisterUnregisterLatch;
+
+        MyDurationScaleChangeListener(AnimationHandler handler, CountDownLatch countDownLatch) {
+            // Call super to construct an inner class
+            handler.super();
+            mRegisterUnregisterLatch = countDownLatch;
+        }
+
+        @Override
+        public boolean register() {
+            mRegisterUnregisterLatch.countDown();
+            assertEquals(1, mRegisterUnregisterLatch.getCount());
+            return super.register();
+        }
+
+        @Override
+        public boolean unregister() {
+            mRegisterUnregisterLatch.countDown();
+            return super.unregister();
+        }
+    }
 }
diff --git a/dynamicanimation/dynamicanimation/src/main/java/androidx/dynamicanimation/animation/AnimationHandler.java b/dynamicanimation/dynamicanimation/src/main/java/androidx/dynamicanimation/animation/AnimationHandler.java
index f5ce59b..121e503 100644
--- a/dynamicanimation/dynamicanimation/src/main/java/androidx/dynamicanimation/animation/AnimationHandler.java
+++ b/dynamicanimation/dynamicanimation/src/main/java/androidx/dynamicanimation/animation/AnimationHandler.java
@@ -16,6 +16,7 @@
 
 package androidx.dynamicanimation.animation;
 
+import android.animation.ValueAnimator;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
@@ -23,6 +24,7 @@
 import android.view.Choreographer;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.VisibleForTesting;
 import androidx.collection.SimpleArrayMap;
@@ -39,7 +41,8 @@
  * AnimationFrameCallbackProvider can be set on the handler to provide timing pulse that
  * may be independent of UI frame update. This could be useful in testing.
  */
-class AnimationHandler {
+@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+public class AnimationHandler {
     /**
      * Callbacks that receives notifications for animation timing
      */
@@ -93,6 +96,11 @@
     @SuppressWarnings("WeakerAccess") /* synthetic access */
     long mCurrentFrameTime = 0;
     private boolean mListDirty = false;
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    public float mDurationScale = 1.0f;
+    @Nullable
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    public DurationScaleChangeListener mDurationScaleChangeListener;
 
     static AnimationHandler getInstance() {
         if (sAnimatorHandler.get() == null) {
@@ -121,6 +129,13 @@
     void addAnimationFrameCallback(final AnimationFrameCallback callback, long delay) {
         if (mAnimationCallbacks.size() == 0) {
             mScheduler.postFrameCallback(mRunnable);
+            if (Build.VERSION.SDK_INT >= 33) {
+                mDurationScale = ValueAnimator.getDurationScale();
+                if (mDurationScaleChangeListener == null) {
+                    mDurationScaleChangeListener = new DurationScaleChangeListener33();
+                }
+                mDurationScaleChangeListener.register();
+            }
         }
         if (!mAnimationCallbacks.contains(callback)) {
             mAnimationCallbacks.add(callback);
@@ -193,6 +208,12 @@
                     mAnimationCallbacks.remove(i);
                 }
             }
+            // Unregister duration scale listener if there are no current animations.
+            if (mAnimationCallbacks.size() == 0) {
+                if (Build.VERSION.SDK_INT >= 33) {
+                    mDurationScaleChangeListener.unregister();
+                }
+            }
             mListDirty = false;
         }
     }
@@ -253,4 +274,55 @@
             return Thread.currentThread() == mHandler.getLooper().getThread();
         }
     }
+
+    /**
+     * Returns the system-wide scaling factor for animations.
+     */
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    public float getDurationScale() {
+        return mDurationScale;
+    }
+
+    /**
+     * T+ listener for changes to the system-wide scaling factor for Animator-based animations.
+     */
+    @RequiresApi(api = 33)
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    public class DurationScaleChangeListener33 implements DurationScaleChangeListener {
+        ValueAnimator.DurationScaleChangeListener mListener;
+
+        @Override
+        public boolean register() {
+            if (mListener == null) {
+                mListener = scale -> AnimationHandler.this.mDurationScale = scale;
+                return ValueAnimator.registerDurationScaleChangeListener(mListener);
+            }
+            return true;
+        }
+
+        @Override
+        public boolean unregister() {
+            boolean unregistered = ValueAnimator.unregisterDurationScaleChangeListener(mListener);
+            mListener = null;
+            return unregistered;
+        }
+    }
+
+    /**
+     * listener for changes to the system-wide scaling factor for Animator-based animations.
+     */
+    @VisibleForTesting
+    public interface DurationScaleChangeListener {
+        /**
+         * Registers a duration scale change listener.
+         * @return true if a listener is registered or one is already registered.
+         */
+        boolean register();
+
+        /**
+         * Unregisters a duration scale change listener.
+         * @return true if a listener is unregistered.
+         */
+        boolean unregister();
+    }
 }
diff --git a/dynamicanimation/dynamicanimation/src/main/java/androidx/dynamicanimation/animation/DynamicAnimation.java b/dynamicanimation/dynamicanimation/src/main/java/androidx/dynamicanimation/animation/DynamicAnimation.java
index c361dd8..58f0842 100644
--- a/dynamicanimation/dynamicanimation/src/main/java/androidx/dynamicanimation/animation/DynamicAnimation.java
+++ b/dynamicanimation/dynamicanimation/src/main/java/androidx/dynamicanimation/animation/DynamicAnimation.java
@@ -25,6 +25,7 @@
 import androidx.annotation.MainThread;
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
+import androidx.annotation.VisibleForTesting;
 import androidx.core.view.ViewCompat;
 
 import java.util.ArrayList;
@@ -676,6 +677,8 @@
         }
         long deltaT = frameTime - mLastFrameTime;
         mLastFrameTime = frameTime;
+        float durationScale = getAnimationHandler().getDurationScale();
+        deltaT = durationScale == 0.0f ? Integer.MAX_VALUE : (long) (deltaT / durationScale);
         boolean finished = updateValueAndVelocity(deltaT);
         // Clamp value & velocity.
         mValue = Math.min(mValue, mMaxValue);
@@ -750,7 +753,8 @@
      * @return the {@link AnimationHandler} for this animator.
      */
     @NonNull
-    AnimationHandler getAnimationHandler() {
+    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+    public AnimationHandler getAnimationHandler() {
         return mAnimationHandler != null ? mAnimationHandler : AnimationHandler.getInstance();
     }
 
diff --git a/exifinterface/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterface.java b/exifinterface/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterface.java
index e5d2274..e1e449f 100644
--- a/exifinterface/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterface.java
+++ b/exifinterface/exifinterface/src/main/java/androidx/exifinterface/media/ExifInterface.java
@@ -5968,7 +5968,11 @@
                 throw new UnsupportedOperationException("Failed to read EXIF from HEIF file. "
                         + "Given stream is either malformed or unsupported.");
             } finally {
-                retriever.release();
+                try {
+                    retriever.release();
+                } catch (IOException e) {
+                    // Nothing we can  do about it.
+                }
             }
         } else {
             throw new UnsupportedOperationException("Reading EXIF from HEIF files "
diff --git a/fragment/fragment-ktx/api/1.5.0-beta01.txt b/fragment/fragment-ktx/api/1.5.0-beta01.txt
deleted file mode 100644
index 6d0a8d3..0000000
--- a/fragment/fragment-ktx/api/1.5.0-beta01.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-// Signature format: 4.0
-package androidx.fragment.app {
-
-  public final class FragmentKt {
-    method public static void clearFragmentResult(androidx.fragment.app.Fragment, String requestKey);
-    method public static void clearFragmentResultListener(androidx.fragment.app.Fragment, String requestKey);
-    method public static void setFragmentResult(androidx.fragment.app.Fragment, String requestKey, android.os.Bundle result);
-    method public static void setFragmentResultListener(androidx.fragment.app.Fragment, String requestKey, kotlin.jvm.functions.Function2<? super java.lang.String,? super android.os.Bundle,kotlin.Unit> listener);
-  }
-
-  public final class FragmentManagerKt {
-    method public static inline void commit(androidx.fragment.app.FragmentManager, optional boolean allowStateLoss, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
-    method public static inline void commitNow(androidx.fragment.app.FragmentManager, optional boolean allowStateLoss, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
-    method @Deprecated public static inline void transaction(androidx.fragment.app.FragmentManager, optional boolean now, optional boolean allowStateLoss, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
-  }
-
-  public final class FragmentTransactionKt {
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction! add(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, optional String tag, optional android.os.Bundle? args);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction! add(androidx.fragment.app.FragmentTransaction, String tag, optional android.os.Bundle? args);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction! replace(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, optional String tag, optional android.os.Bundle? args);
-  }
-
-  public final class FragmentViewModelLazyKt {
-    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! activityViewModels(androidx.fragment.app.Fragment, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! activityViewModels(androidx.fragment.app.Fragment, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static <VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> createViewModelLazy(androidx.fragment.app.Fragment, kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras> extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @Deprecated @MainThread public static <VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! createViewModelLazy(androidx.fragment.app.Fragment, kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! viewModels(androidx.fragment.app.Fragment, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! viewModels(androidx.fragment.app.Fragment, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-  }
-
-  public final class ViewKt {
-    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
-  }
-
-}
-
diff --git a/fragment/fragment-ktx/api/public_plus_experimental_1.5.0-beta01.txt b/fragment/fragment-ktx/api/public_plus_experimental_1.5.0-beta01.txt
deleted file mode 100644
index 6d0a8d3..0000000
--- a/fragment/fragment-ktx/api/public_plus_experimental_1.5.0-beta01.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-// Signature format: 4.0
-package androidx.fragment.app {
-
-  public final class FragmentKt {
-    method public static void clearFragmentResult(androidx.fragment.app.Fragment, String requestKey);
-    method public static void clearFragmentResultListener(androidx.fragment.app.Fragment, String requestKey);
-    method public static void setFragmentResult(androidx.fragment.app.Fragment, String requestKey, android.os.Bundle result);
-    method public static void setFragmentResultListener(androidx.fragment.app.Fragment, String requestKey, kotlin.jvm.functions.Function2<? super java.lang.String,? super android.os.Bundle,kotlin.Unit> listener);
-  }
-
-  public final class FragmentManagerKt {
-    method public static inline void commit(androidx.fragment.app.FragmentManager, optional boolean allowStateLoss, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
-    method public static inline void commitNow(androidx.fragment.app.FragmentManager, optional boolean allowStateLoss, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
-    method @Deprecated public static inline void transaction(androidx.fragment.app.FragmentManager, optional boolean now, optional boolean allowStateLoss, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
-  }
-
-  public final class FragmentTransactionKt {
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction! add(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, optional String tag, optional android.os.Bundle? args);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction! add(androidx.fragment.app.FragmentTransaction, String tag, optional android.os.Bundle? args);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction! replace(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, optional String tag, optional android.os.Bundle? args);
-  }
-
-  public final class FragmentViewModelLazyKt {
-    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! activityViewModels(androidx.fragment.app.Fragment, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! activityViewModels(androidx.fragment.app.Fragment, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static <VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> createViewModelLazy(androidx.fragment.app.Fragment, kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras> extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @Deprecated @MainThread public static <VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! createViewModelLazy(androidx.fragment.app.Fragment, kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! viewModels(androidx.fragment.app.Fragment, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! viewModels(androidx.fragment.app.Fragment, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-  }
-
-  public final class ViewKt {
-    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
-  }
-
-}
-
diff --git a/fragment/fragment-ktx/api/res-1.5.0-beta01.txt b/fragment/fragment-ktx/api/res-1.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/fragment/fragment-ktx/api/res-1.5.0-beta01.txt
+++ /dev/null
diff --git a/fragment/fragment-ktx/api/restricted_1.5.0-beta01.txt b/fragment/fragment-ktx/api/restricted_1.5.0-beta01.txt
deleted file mode 100644
index 6d0a8d3..0000000
--- a/fragment/fragment-ktx/api/restricted_1.5.0-beta01.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-// Signature format: 4.0
-package androidx.fragment.app {
-
-  public final class FragmentKt {
-    method public static void clearFragmentResult(androidx.fragment.app.Fragment, String requestKey);
-    method public static void clearFragmentResultListener(androidx.fragment.app.Fragment, String requestKey);
-    method public static void setFragmentResult(androidx.fragment.app.Fragment, String requestKey, android.os.Bundle result);
-    method public static void setFragmentResultListener(androidx.fragment.app.Fragment, String requestKey, kotlin.jvm.functions.Function2<? super java.lang.String,? super android.os.Bundle,kotlin.Unit> listener);
-  }
-
-  public final class FragmentManagerKt {
-    method public static inline void commit(androidx.fragment.app.FragmentManager, optional boolean allowStateLoss, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
-    method public static inline void commitNow(androidx.fragment.app.FragmentManager, optional boolean allowStateLoss, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
-    method @Deprecated public static inline void transaction(androidx.fragment.app.FragmentManager, optional boolean now, optional boolean allowStateLoss, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
-  }
-
-  public final class FragmentTransactionKt {
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction! add(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, optional String tag, optional android.os.Bundle? args);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction! add(androidx.fragment.app.FragmentTransaction, String tag, optional android.os.Bundle? args);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction! replace(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, optional String tag, optional android.os.Bundle? args);
-  }
-
-  public final class FragmentViewModelLazyKt {
-    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! activityViewModels(androidx.fragment.app.Fragment, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! activityViewModels(androidx.fragment.app.Fragment, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static <VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> createViewModelLazy(androidx.fragment.app.Fragment, kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras> extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @Deprecated @MainThread public static <VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! createViewModelLazy(androidx.fragment.app.Fragment, kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! viewModels(androidx.fragment.app.Fragment, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! viewModels(androidx.fragment.app.Fragment, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-  }
-
-  public final class ViewKt {
-    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
-  }
-
-}
-
diff --git a/fragment/fragment-testing/api/1.5.0-beta01.txt b/fragment/fragment-testing/api/1.5.0-beta01.txt
deleted file mode 100644
index e784213..0000000
--- a/fragment/fragment-testing/api/1.5.0-beta01.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-// Signature format: 4.0
-package androidx.fragment.app.testing {
-
-  public final class FragmentScenario<F extends androidx.fragment.app.Fragment> implements java.io.Closeable {
-    method public void close();
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, @StyleRes int themeResId, androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, @StyleRes int themeResId, androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass);
-    method public androidx.fragment.app.testing.FragmentScenario<F> moveToState(androidx.lifecycle.Lifecycle.State newState);
-    method public androidx.fragment.app.testing.FragmentScenario<F> onFragment(androidx.fragment.app.testing.FragmentScenario.FragmentAction<F> action);
-    method public androidx.fragment.app.testing.FragmentScenario<F> recreate();
-    field public static final androidx.fragment.app.testing.FragmentScenario.Companion Companion;
-  }
-
-  public static final class FragmentScenario.Companion {
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, @StyleRes int themeResId, androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, @StyleRes int themeResId, androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass);
-  }
-
-  public static fun interface FragmentScenario.FragmentAction<F extends androidx.fragment.app.Fragment> {
-    method public void perform(F fragment);
-  }
-
-  public final class FragmentScenarioKt {
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.fragment.app.FragmentFactory? factory);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, kotlin.jvm.functions.Function0<? extends F> instantiate);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, kotlin.jvm.functions.Function0<? extends F> instantiate);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.fragment.app.FragmentFactory? factory);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, kotlin.jvm.functions.Function0<? extends F> instantiate);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, kotlin.jvm.functions.Function0<? extends F> instantiate);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, T> T! withFragment(androidx.fragment.app.testing.FragmentScenario<F>, kotlin.jvm.functions.Function1<? super F,? extends T> block);
-  }
-
-}
-
diff --git a/fragment/fragment-testing/api/public_plus_experimental_1.5.0-beta01.txt b/fragment/fragment-testing/api/public_plus_experimental_1.5.0-beta01.txt
deleted file mode 100644
index e784213..0000000
--- a/fragment/fragment-testing/api/public_plus_experimental_1.5.0-beta01.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-// Signature format: 4.0
-package androidx.fragment.app.testing {
-
-  public final class FragmentScenario<F extends androidx.fragment.app.Fragment> implements java.io.Closeable {
-    method public void close();
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, @StyleRes int themeResId, androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, @StyleRes int themeResId, androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass);
-    method public androidx.fragment.app.testing.FragmentScenario<F> moveToState(androidx.lifecycle.Lifecycle.State newState);
-    method public androidx.fragment.app.testing.FragmentScenario<F> onFragment(androidx.fragment.app.testing.FragmentScenario.FragmentAction<F> action);
-    method public androidx.fragment.app.testing.FragmentScenario<F> recreate();
-    field public static final androidx.fragment.app.testing.FragmentScenario.Companion Companion;
-  }
-
-  public static final class FragmentScenario.Companion {
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, @StyleRes int themeResId, androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, @StyleRes int themeResId, androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass);
-  }
-
-  public static fun interface FragmentScenario.FragmentAction<F extends androidx.fragment.app.Fragment> {
-    method public void perform(F fragment);
-  }
-
-  public final class FragmentScenarioKt {
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.fragment.app.FragmentFactory? factory);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, kotlin.jvm.functions.Function0<? extends F> instantiate);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, kotlin.jvm.functions.Function0<? extends F> instantiate);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.fragment.app.FragmentFactory? factory);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, kotlin.jvm.functions.Function0<? extends F> instantiate);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, kotlin.jvm.functions.Function0<? extends F> instantiate);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, T> T! withFragment(androidx.fragment.app.testing.FragmentScenario<F>, kotlin.jvm.functions.Function1<? super F,? extends T> block);
-  }
-
-}
-
diff --git a/fragment/fragment-testing/api/res-1.5.0-beta01.txt b/fragment/fragment-testing/api/res-1.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/fragment/fragment-testing/api/res-1.5.0-beta01.txt
+++ /dev/null
diff --git a/fragment/fragment-testing/api/restricted_1.5.0-beta01.txt b/fragment/fragment-testing/api/restricted_1.5.0-beta01.txt
deleted file mode 100644
index e784213..0000000
--- a/fragment/fragment-testing/api/restricted_1.5.0-beta01.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-// Signature format: 4.0
-package androidx.fragment.app.testing {
-
-  public final class FragmentScenario<F extends androidx.fragment.app.Fragment> implements java.io.Closeable {
-    method public void close();
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, @StyleRes int themeResId, androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, @StyleRes int themeResId, androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs);
-    method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass);
-    method public androidx.fragment.app.testing.FragmentScenario<F> moveToState(androidx.lifecycle.Lifecycle.State newState);
-    method public androidx.fragment.app.testing.FragmentScenario<F> onFragment(androidx.fragment.app.testing.FragmentScenario.FragmentAction<F> action);
-    method public androidx.fragment.app.testing.FragmentScenario<F> recreate();
-    field public static final androidx.fragment.app.testing.FragmentScenario.Companion Companion;
-  }
-
-  public static final class FragmentScenario.Companion {
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, @StyleRes int themeResId, androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launch(Class<F> fragmentClass);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, android.os.Bundle? fragmentArgs, @StyleRes int themeResId, androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass, optional android.os.Bundle? fragmentArgs);
-    method public <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchInContainer(Class<F> fragmentClass);
-  }
-
-  public static fun interface FragmentScenario.FragmentAction<F extends androidx.fragment.app.Fragment> {
-    method public void perform(F fragment);
-  }
-
-  public final class FragmentScenarioKt {
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.fragment.app.FragmentFactory? factory);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, kotlin.jvm.functions.Function0<? extends F> instantiate);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragment(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, kotlin.jvm.functions.Function0<? extends F> instantiate);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.fragment.app.FragmentFactory? factory);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, kotlin.jvm.functions.Function0<? extends F> instantiate);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, optional androidx.fragment.app.FragmentFactory? factory);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F>! launchFragmentInContainer(optional android.os.Bundle? fragmentArgs, optional @StyleRes int themeResId, optional androidx.lifecycle.Lifecycle.State initialState, kotlin.jvm.functions.Function0<? extends F> instantiate);
-    method public static inline <reified F extends androidx.fragment.app.Fragment, T> T! withFragment(androidx.fragment.app.testing.FragmentScenario<F>, kotlin.jvm.functions.Function1<? super F,? extends T> block);
-  }
-
-}
-
diff --git a/fragment/fragment/api/1.5.0-beta01.txt b/fragment/fragment/api/1.5.0-beta01.txt
deleted file mode 100644
index 32377c9..0000000
--- a/fragment/fragment/api/1.5.0-beta01.txt
+++ /dev/null
@@ -1,543 +0,0 @@
-// Signature format: 4.0
-package androidx.fragment.app {
-
-  public class DialogFragment extends androidx.fragment.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
-    ctor public DialogFragment();
-    ctor public DialogFragment(@LayoutRes int);
-    method public void dismiss();
-    method public void dismissAllowingStateLoss();
-    method @MainThread public void dismissNow();
-    method public android.app.Dialog? getDialog();
-    method public boolean getShowsDialog();
-    method @StyleRes public int getTheme();
-    method public boolean isCancelable();
-    method public void onCancel(android.content.DialogInterface);
-    method @MainThread public android.app.Dialog onCreateDialog(android.os.Bundle?);
-    method public void onDismiss(android.content.DialogInterface);
-    method public final android.app.Dialog requireDialog();
-    method public void setCancelable(boolean);
-    method public void setShowsDialog(boolean);
-    method public void setStyle(int, @StyleRes int);
-    method public void show(androidx.fragment.app.FragmentManager, String?);
-    method public int show(androidx.fragment.app.FragmentTransaction, String?);
-    method public void showNow(androidx.fragment.app.FragmentManager, String?);
-    field public static final int STYLE_NORMAL = 0; // 0x0
-    field public static final int STYLE_NO_FRAME = 2; // 0x2
-    field public static final int STYLE_NO_INPUT = 3; // 0x3
-    field public static final int STYLE_NO_TITLE = 1; // 0x1
-  }
-
-  public class Fragment implements androidx.activity.result.ActivityResultCaller android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
-    ctor public Fragment();
-    ctor @ContentView public Fragment(@LayoutRes int);
-    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
-    method public final boolean equals(Object?);
-    method public final androidx.fragment.app.FragmentActivity? getActivity();
-    method public boolean getAllowEnterTransitionOverlap();
-    method public boolean getAllowReturnTransitionOverlap();
-    method public final android.os.Bundle? getArguments();
-    method public final androidx.fragment.app.FragmentManager getChildFragmentManager();
-    method public android.content.Context? getContext();
-    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
-    method public Object? getEnterTransition();
-    method public Object? getExitTransition();
-    method @Deprecated public final androidx.fragment.app.FragmentManager? getFragmentManager();
-    method public final Object? getHost();
-    method public final int getId();
-    method public final android.view.LayoutInflater getLayoutInflater();
-    method public androidx.lifecycle.Lifecycle getLifecycle();
-    method @Deprecated public androidx.loader.app.LoaderManager getLoaderManager();
-    method public final androidx.fragment.app.Fragment? getParentFragment();
-    method public final androidx.fragment.app.FragmentManager getParentFragmentManager();
-    method public Object? getReenterTransition();
-    method public final android.content.res.Resources getResources();
-    method @Deprecated public final boolean getRetainInstance();
-    method public Object? getReturnTransition();
-    method public final androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
-    method public Object? getSharedElementEnterTransition();
-    method public Object? getSharedElementReturnTransition();
-    method public final String getString(@StringRes int);
-    method public final String getString(@StringRes int, java.lang.Object!...);
-    method public final String? getTag();
-    method @Deprecated public final androidx.fragment.app.Fragment? getTargetFragment();
-    method @Deprecated public final int getTargetRequestCode();
-    method public final CharSequence getText(@StringRes int);
-    method @Deprecated public boolean getUserVisibleHint();
-    method public android.view.View? getView();
-    method @MainThread public androidx.lifecycle.LifecycleOwner getViewLifecycleOwner();
-    method public androidx.lifecycle.LiveData<androidx.lifecycle.LifecycleOwner!> getViewLifecycleOwnerLiveData();
-    method public androidx.lifecycle.ViewModelStore getViewModelStore();
-    method public final int hashCode();
-    method @Deprecated public static androidx.fragment.app.Fragment instantiate(android.content.Context, String);
-    method @Deprecated public static androidx.fragment.app.Fragment instantiate(android.content.Context, String, android.os.Bundle?);
-    method public final boolean isAdded();
-    method public final boolean isDetached();
-    method public final boolean isHidden();
-    method public final boolean isInLayout();
-    method public final boolean isRemoving();
-    method public final boolean isResumed();
-    method public final boolean isStateSaved();
-    method public final boolean isVisible();
-    method @Deprecated @CallSuper @MainThread public void onActivityCreated(android.os.Bundle?);
-    method @Deprecated public void onActivityResult(int, int, android.content.Intent?);
-    method @CallSuper @MainThread public void onAttach(android.content.Context);
-    method @Deprecated @CallSuper @MainThread public void onAttach(android.app.Activity);
-    method @Deprecated @MainThread public void onAttachFragment(androidx.fragment.app.Fragment);
-    method @CallSuper public void onConfigurationChanged(android.content.res.Configuration);
-    method @MainThread public boolean onContextItemSelected(android.view.MenuItem);
-    method @CallSuper @MainThread public void onCreate(android.os.Bundle?);
-    method @MainThread public android.view.animation.Animation? onCreateAnimation(int, boolean, int);
-    method @MainThread public android.animation.Animator? onCreateAnimator(int, boolean, int);
-    method @MainThread public void onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo?);
-    method @Deprecated @MainThread public void onCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
-    method @MainThread public android.view.View? onCreateView(android.view.LayoutInflater, android.view.ViewGroup?, android.os.Bundle?);
-    method @CallSuper @MainThread public void onDestroy();
-    method @Deprecated @MainThread public void onDestroyOptionsMenu();
-    method @CallSuper @MainThread public void onDestroyView();
-    method @CallSuper @MainThread public void onDetach();
-    method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle?);
-    method @MainThread public void onHiddenChanged(boolean);
-    method @CallSuper @UiThread public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle?);
-    method @Deprecated @CallSuper @UiThread public void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle?);
-    method @CallSuper @MainThread public void onLowMemory();
-    method public void onMultiWindowModeChanged(boolean);
-    method @Deprecated @MainThread public boolean onOptionsItemSelected(android.view.MenuItem);
-    method @Deprecated @MainThread public void onOptionsMenuClosed(android.view.Menu);
-    method @CallSuper @MainThread public void onPause();
-    method public void onPictureInPictureModeChanged(boolean);
-    method @Deprecated @MainThread public void onPrepareOptionsMenu(android.view.Menu);
-    method @MainThread public void onPrimaryNavigationFragmentChanged(boolean);
-    method @Deprecated public void onRequestPermissionsResult(int, String![], int[]);
-    method @CallSuper @MainThread public void onResume();
-    method @MainThread public void onSaveInstanceState(android.os.Bundle);
-    method @CallSuper @MainThread public void onStart();
-    method @CallSuper @MainThread public void onStop();
-    method @MainThread public void onViewCreated(android.view.View, android.os.Bundle?);
-    method @CallSuper @MainThread public void onViewStateRestored(android.os.Bundle?);
-    method public void postponeEnterTransition();
-    method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
-    method @MainThread public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
-    method @MainThread 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 void registerForContextMenu(android.view.View);
-    method @Deprecated public final void requestPermissions(String![], int);
-    method public final androidx.fragment.app.FragmentActivity requireActivity();
-    method public final android.os.Bundle requireArguments();
-    method public final android.content.Context requireContext();
-    method @Deprecated public final androidx.fragment.app.FragmentManager requireFragmentManager();
-    method public final Object requireHost();
-    method public final androidx.fragment.app.Fragment requireParentFragment();
-    method public final android.view.View requireView();
-    method public void setAllowEnterTransitionOverlap(boolean);
-    method public void setAllowReturnTransitionOverlap(boolean);
-    method public void setArguments(android.os.Bundle?);
-    method public void setEnterSharedElementCallback(androidx.core.app.SharedElementCallback?);
-    method public void setEnterTransition(Object?);
-    method public void setExitSharedElementCallback(androidx.core.app.SharedElementCallback?);
-    method public void setExitTransition(Object?);
-    method @Deprecated public void setHasOptionsMenu(boolean);
-    method public void setInitialSavedState(androidx.fragment.app.Fragment.SavedState?);
-    method public void setMenuVisibility(boolean);
-    method public void setReenterTransition(Object?);
-    method @Deprecated public void setRetainInstance(boolean);
-    method public void setReturnTransition(Object?);
-    method public void setSharedElementEnterTransition(Object?);
-    method public void setSharedElementReturnTransition(Object?);
-    method @Deprecated public void setTargetFragment(androidx.fragment.app.Fragment?, int);
-    method @Deprecated public void setUserVisibleHint(boolean);
-    method public boolean shouldShowRequestPermissionRationale(String);
-    method public void startActivity(android.content.Intent!);
-    method public void startActivity(android.content.Intent!, android.os.Bundle?);
-    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, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
-    method public void startPostponedEnterTransition();
-    method public void unregisterForContextMenu(android.view.View);
-  }
-
-  public static class Fragment.InstantiationException extends java.lang.RuntimeException {
-    ctor public Fragment.InstantiationException(String, Exception?);
-  }
-
-  public static class Fragment.SavedState implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<androidx.fragment.app.Fragment.SavedState!> CREATOR;
-  }
-
-  public class FragmentActivity extends androidx.activity.ComponentActivity implements androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback androidx.lifecycle.LifecycleOwner {
-    ctor public FragmentActivity();
-    ctor @ContentView public FragmentActivity(@LayoutRes int);
-    method public androidx.fragment.app.FragmentManager getSupportFragmentManager();
-    method @Deprecated public androidx.loader.app.LoaderManager getSupportLoaderManager();
-    method @Deprecated @MainThread public void onAttachFragment(androidx.fragment.app.Fragment);
-    method protected void onResumeFragments();
-    method public void onStateNotSaved();
-    method public void setEnterSharedElementCallback(androidx.core.app.SharedElementCallback?);
-    method public void setExitSharedElementCallback(androidx.core.app.SharedElementCallback?);
-    method public void startActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int);
-    method public void startActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int, android.os.Bundle?);
-    method @Deprecated public void startIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
-    method public void supportFinishAfterTransition();
-    method @Deprecated public void supportInvalidateOptionsMenu();
-    method public void supportPostponeEnterTransition();
-    method public void supportStartPostponedEnterTransition();
-    method @Deprecated public final void validateRequestPermissionsRequestCode(int);
-  }
-
-  public abstract class FragmentContainer {
-    ctor public FragmentContainer();
-    method @Deprecated public androidx.fragment.app.Fragment instantiate(android.content.Context, String, android.os.Bundle?);
-    method public abstract android.view.View? onFindViewById(@IdRes int);
-    method public abstract boolean onHasView();
-  }
-
-  public final class FragmentContainerView extends android.widget.FrameLayout {
-    ctor public FragmentContainerView(android.content.Context context);
-    ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
-    ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
-    method public <F extends androidx.fragment.app.Fragment> F! getFragment();
-  }
-
-  public class FragmentController {
-    method public void attachHost(androidx.fragment.app.Fragment?);
-    method public static androidx.fragment.app.FragmentController createController(androidx.fragment.app.FragmentHostCallback<?>);
-    method public void dispatchActivityCreated();
-    method @Deprecated public void dispatchConfigurationChanged(android.content.res.Configuration);
-    method public boolean dispatchContextItemSelected(android.view.MenuItem);
-    method public void dispatchCreate();
-    method @Deprecated public boolean dispatchCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
-    method public void dispatchDestroy();
-    method public void dispatchDestroyView();
-    method @Deprecated public void dispatchLowMemory();
-    method @Deprecated public void dispatchMultiWindowModeChanged(boolean);
-    method @Deprecated public boolean dispatchOptionsItemSelected(android.view.MenuItem);
-    method @Deprecated public void dispatchOptionsMenuClosed(android.view.Menu);
-    method public void dispatchPause();
-    method @Deprecated public void dispatchPictureInPictureModeChanged(boolean);
-    method @Deprecated public boolean dispatchPrepareOptionsMenu(android.view.Menu);
-    method @Deprecated public void dispatchReallyStop();
-    method public void dispatchResume();
-    method public void dispatchStart();
-    method public void dispatchStop();
-    method @Deprecated public void doLoaderDestroy();
-    method @Deprecated public void doLoaderRetain();
-    method @Deprecated public void doLoaderStart();
-    method @Deprecated public void doLoaderStop(boolean);
-    method @Deprecated public void dumpLoaders(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
-    method public boolean execPendingActions();
-    method public androidx.fragment.app.Fragment? findFragmentByWho(String);
-    method public java.util.List<androidx.fragment.app.Fragment!> getActiveFragments(java.util.List<androidx.fragment.app.Fragment!>!);
-    method public int getActiveFragmentsCount();
-    method public androidx.fragment.app.FragmentManager getSupportFragmentManager();
-    method @Deprecated public androidx.loader.app.LoaderManager! getSupportLoaderManager();
-    method public void noteStateNotSaved();
-    method public android.view.View? onCreateView(android.view.View?, String, android.content.Context, android.util.AttributeSet);
-    method @Deprecated public void reportLoaderStart();
-    method @Deprecated public void restoreAllState(android.os.Parcelable?, java.util.List<androidx.fragment.app.Fragment!>?);
-    method @Deprecated public void restoreAllState(android.os.Parcelable?, androidx.fragment.app.FragmentManagerNonConfig?);
-    method @Deprecated public void restoreLoaderNonConfig(androidx.collection.SimpleArrayMap<java.lang.String!,androidx.loader.app.LoaderManager!>!);
-    method @Deprecated public void restoreSaveState(android.os.Parcelable?);
-    method @Deprecated public androidx.collection.SimpleArrayMap<java.lang.String!,androidx.loader.app.LoaderManager!>? retainLoaderNonConfig();
-    method @Deprecated public androidx.fragment.app.FragmentManagerNonConfig? retainNestedNonConfig();
-    method @Deprecated public java.util.List<androidx.fragment.app.Fragment!>? retainNonConfig();
-    method @Deprecated public android.os.Parcelable? saveAllState();
-  }
-
-  public class FragmentFactory {
-    ctor public FragmentFactory();
-    method public androidx.fragment.app.Fragment instantiate(ClassLoader, String);
-    method public static Class<? extends androidx.fragment.app.Fragment> loadFragmentClass(ClassLoader, String);
-  }
-
-  public abstract class FragmentHostCallback<E> extends androidx.fragment.app.FragmentContainer {
-    ctor public FragmentHostCallback(android.content.Context, android.os.Handler, int);
-    method public void onDump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
-    method public android.view.View? onFindViewById(int);
-    method public abstract E? onGetHost();
-    method public android.view.LayoutInflater onGetLayoutInflater();
-    method public int onGetWindowAnimations();
-    method public boolean onHasView();
-    method public boolean onHasWindowAnimations();
-    method @Deprecated public void onRequestPermissionsFromFragment(androidx.fragment.app.Fragment, String![], int);
-    method public boolean onShouldSaveFragmentState(androidx.fragment.app.Fragment);
-    method public boolean onShouldShowRequestPermissionRationale(String);
-    method public void onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int);
-    method public void onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int, android.os.Bundle?);
-    method @Deprecated public void onStartIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
-    method public void onSupportInvalidateOptionsMenu();
-  }
-
-  public abstract class FragmentManager implements androidx.fragment.app.FragmentResultOwner {
-    ctor public FragmentManager();
-    method public void addFragmentOnAttachListener(androidx.fragment.app.FragmentOnAttachListener);
-    method public void addOnBackStackChangedListener(androidx.fragment.app.FragmentManager.OnBackStackChangedListener);
-    method public androidx.fragment.app.FragmentTransaction beginTransaction();
-    method public void clearBackStack(String);
-    method public final void clearFragmentResult(String);
-    method public final void clearFragmentResultListener(String);
-    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
-    method @Deprecated public static void enableDebugLogging(boolean);
-    method public boolean executePendingTransactions();
-    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
-    method public androidx.fragment.app.Fragment? findFragmentById(@IdRes int);
-    method public androidx.fragment.app.Fragment? findFragmentByTag(String?);
-    method public androidx.fragment.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
-    method public int getBackStackEntryCount();
-    method public androidx.fragment.app.Fragment? getFragment(android.os.Bundle, String);
-    method public androidx.fragment.app.FragmentFactory getFragmentFactory();
-    method public java.util.List<androidx.fragment.app.Fragment!> getFragments();
-    method public androidx.fragment.app.Fragment? getPrimaryNavigationFragment();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy? getStrictModePolicy();
-    method public boolean isDestroyed();
-    method public boolean isStateSaved();
-    method public void popBackStack();
-    method public void popBackStack(String?, int);
-    method public void popBackStack(int, int);
-    method public boolean popBackStackImmediate();
-    method public boolean popBackStackImmediate(String?, int);
-    method public boolean popBackStackImmediate(int, int);
-    method public void putFragment(android.os.Bundle, String, androidx.fragment.app.Fragment);
-    method public void registerFragmentLifecycleCallbacks(androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks, boolean);
-    method public void removeFragmentOnAttachListener(androidx.fragment.app.FragmentOnAttachListener);
-    method public void removeOnBackStackChangedListener(androidx.fragment.app.FragmentManager.OnBackStackChangedListener);
-    method public void restoreBackStack(String);
-    method public void saveBackStack(String);
-    method public androidx.fragment.app.Fragment.SavedState? saveFragmentInstanceState(androidx.fragment.app.Fragment);
-    method public void setFragmentFactory(androidx.fragment.app.FragmentFactory);
-    method public final void setFragmentResult(String, android.os.Bundle);
-    method public final void setFragmentResultListener(String, androidx.lifecycle.LifecycleOwner, androidx.fragment.app.FragmentResultListener);
-    method public void setStrictModePolicy(androidx.fragment.app.strictmode.FragmentStrictMode.Policy?);
-    method public void unregisterFragmentLifecycleCallbacks(androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks);
-    field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
-  }
-
-  public static interface FragmentManager.BackStackEntry {
-    method @Deprecated public CharSequence? getBreadCrumbShortTitle();
-    method @Deprecated @StringRes public int getBreadCrumbShortTitleRes();
-    method @Deprecated public CharSequence? getBreadCrumbTitle();
-    method @Deprecated @StringRes public int getBreadCrumbTitleRes();
-    method public int getId();
-    method public String? getName();
-  }
-
-  public abstract static class FragmentManager.FragmentLifecycleCallbacks {
-    ctor public FragmentManager.FragmentLifecycleCallbacks();
-    method @Deprecated public void onFragmentActivityCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
-    method public void onFragmentAttached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.content.Context);
-    method public void onFragmentCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
-    method public void onFragmentDestroyed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentDetached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentPaused(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentPreAttached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.content.Context);
-    method public void onFragmentPreCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
-    method public void onFragmentResumed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentSaveInstanceState(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle);
-    method public void onFragmentStarted(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentStopped(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentViewCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.view.View, android.os.Bundle?);
-    method public void onFragmentViewDestroyed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-  }
-
-  public static interface FragmentManager.OnBackStackChangedListener {
-    method @MainThread public void onBackStackChanged();
-  }
-
-  @Deprecated public class FragmentManagerNonConfig {
-  }
-
-  public interface FragmentOnAttachListener {
-    method @MainThread public void onAttachFragment(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-  }
-
-  @Deprecated public abstract class FragmentPagerAdapter extends androidx.viewpager.widget.PagerAdapter {
-    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager);
-    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager, int);
-    method @Deprecated public abstract androidx.fragment.app.Fragment getItem(int);
-    method @Deprecated public long getItemId(int);
-    method @Deprecated public boolean isViewFromObject(android.view.View, Object);
-    field @Deprecated public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1; // 0x1
-    field @Deprecated public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0; // 0x0
-  }
-
-  public interface FragmentResultListener {
-    method public void onFragmentResult(String, android.os.Bundle);
-  }
-
-  public interface FragmentResultOwner {
-    method public void clearFragmentResult(String);
-    method public void clearFragmentResultListener(String);
-    method public void setFragmentResult(String, android.os.Bundle);
-    method public void setFragmentResultListener(String, androidx.lifecycle.LifecycleOwner, androidx.fragment.app.FragmentResultListener);
-  }
-
-  @Deprecated public abstract class FragmentStatePagerAdapter extends androidx.viewpager.widget.PagerAdapter {
-    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager);
-    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager, int);
-    method @Deprecated public abstract androidx.fragment.app.Fragment getItem(int);
-    method @Deprecated public boolean isViewFromObject(android.view.View, Object);
-    field @Deprecated public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1; // 0x1
-    field @Deprecated public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0; // 0x0
-  }
-
-  @Deprecated public class FragmentTabHost extends android.widget.TabHost implements android.widget.TabHost.OnTabChangeListener {
-    ctor @Deprecated public FragmentTabHost(android.content.Context);
-    ctor @Deprecated public FragmentTabHost(android.content.Context, android.util.AttributeSet?);
-    method @Deprecated public void addTab(android.widget.TabHost.TabSpec, Class<?>, android.os.Bundle?);
-    method @Deprecated public void onTabChanged(String?);
-    method @Deprecated public void setup(android.content.Context, androidx.fragment.app.FragmentManager);
-    method @Deprecated public void setup(android.content.Context, androidx.fragment.app.FragmentManager, int);
-  }
-
-  public abstract class FragmentTransaction {
-    ctor @Deprecated public FragmentTransaction();
-    method public final androidx.fragment.app.FragmentTransaction add(Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
-    method public androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.Fragment, String?);
-    method public final androidx.fragment.app.FragmentTransaction add(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?);
-    method public androidx.fragment.app.FragmentTransaction add(@IdRes int, androidx.fragment.app.Fragment);
-    method public final androidx.fragment.app.FragmentTransaction add(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
-    method public androidx.fragment.app.FragmentTransaction add(@IdRes int, androidx.fragment.app.Fragment, String?);
-    method public androidx.fragment.app.FragmentTransaction addSharedElement(android.view.View, String);
-    method public androidx.fragment.app.FragmentTransaction addToBackStack(String?);
-    method public androidx.fragment.app.FragmentTransaction attach(androidx.fragment.app.Fragment);
-    method public abstract int commit();
-    method public abstract int commitAllowingStateLoss();
-    method public abstract void commitNow();
-    method public abstract void commitNowAllowingStateLoss();
-    method public androidx.fragment.app.FragmentTransaction detach(androidx.fragment.app.Fragment);
-    method public androidx.fragment.app.FragmentTransaction disallowAddToBackStack();
-    method public androidx.fragment.app.FragmentTransaction hide(androidx.fragment.app.Fragment);
-    method public boolean isAddToBackStackAllowed();
-    method public boolean isEmpty();
-    method public androidx.fragment.app.FragmentTransaction remove(androidx.fragment.app.Fragment);
-    method public final androidx.fragment.app.FragmentTransaction replace(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?);
-    method public androidx.fragment.app.FragmentTransaction replace(@IdRes int, androidx.fragment.app.Fragment);
-    method public final androidx.fragment.app.FragmentTransaction replace(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
-    method public androidx.fragment.app.FragmentTransaction replace(@IdRes int, androidx.fragment.app.Fragment, String?);
-    method public androidx.fragment.app.FragmentTransaction runOnCommit(Runnable);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setAllowOptimization(boolean);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbShortTitle(@StringRes int);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbShortTitle(CharSequence?);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbTitle(@StringRes int);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbTitle(CharSequence?);
-    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int);
-    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int);
-    method public androidx.fragment.app.FragmentTransaction setMaxLifecycle(androidx.fragment.app.Fragment, androidx.lifecycle.Lifecycle.State);
-    method public androidx.fragment.app.FragmentTransaction setPrimaryNavigationFragment(androidx.fragment.app.Fragment?);
-    method public androidx.fragment.app.FragmentTransaction setReorderingAllowed(boolean);
-    method public androidx.fragment.app.FragmentTransaction setTransition(int);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setTransitionStyle(@StyleRes int);
-    method public androidx.fragment.app.FragmentTransaction show(androidx.fragment.app.Fragment);
-    field public static final int TRANSIT_ENTER_MASK = 4096; // 0x1000
-    field public static final int TRANSIT_EXIT_MASK = 8192; // 0x2000
-    field public static final int TRANSIT_FRAGMENT_CLOSE = 8194; // 0x2002
-    field public static final int TRANSIT_FRAGMENT_FADE = 4099; // 0x1003
-    field public static final int TRANSIT_FRAGMENT_MATCH_ACTIVITY_CLOSE = 8197; // 0x2005
-    field public static final int TRANSIT_FRAGMENT_MATCH_ACTIVITY_OPEN = 4100; // 0x1004
-    field public static final int TRANSIT_FRAGMENT_OPEN = 4097; // 0x1001
-    field public static final int TRANSIT_NONE = 0; // 0x0
-    field public static final int TRANSIT_UNSET = -1; // 0xffffffff
-  }
-
-  public class ListFragment extends androidx.fragment.app.Fragment {
-    ctor public ListFragment();
-    method public android.widget.ListAdapter? getListAdapter();
-    method public android.widget.ListView getListView();
-    method public long getSelectedItemId();
-    method public int getSelectedItemPosition();
-    method public void onListItemClick(android.widget.ListView, android.view.View, int, long);
-    method public final android.widget.ListAdapter requireListAdapter();
-    method public void setEmptyText(CharSequence?);
-    method public void setListAdapter(android.widget.ListAdapter?);
-    method public void setListShown(boolean);
-    method public void setListShownNoAnimation(boolean);
-    method public void setSelection(int);
-  }
-
-}
-
-package androidx.fragment.app.strictmode {
-
-  public final class FragmentReuseViolation extends androidx.fragment.app.strictmode.Violation {
-    method public String getPreviousFragmentId();
-    property public final String previousFragmentId;
-  }
-
-  public final class FragmentStrictMode {
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy getDefaultPolicy();
-    method @VisibleForTesting public void onPolicyViolation(androidx.fragment.app.strictmode.Violation violation);
-    method public void setDefaultPolicy(androidx.fragment.app.strictmode.FragmentStrictMode.Policy);
-    property public final androidx.fragment.app.strictmode.FragmentStrictMode.Policy defaultPolicy;
-    field public static final androidx.fragment.app.strictmode.FragmentStrictMode INSTANCE;
-  }
-
-  public static fun interface FragmentStrictMode.OnViolationListener {
-    method public void onViolation(androidx.fragment.app.strictmode.Violation violation);
-  }
-
-  public static final class FragmentStrictMode.Policy {
-    field public static final androidx.fragment.app.strictmode.FragmentStrictMode.Policy LAX;
-  }
-
-  public static final class FragmentStrictMode.Policy.Builder {
-    ctor public FragmentStrictMode.Policy.Builder();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder allowViolation(Class<? extends androidx.fragment.app.Fragment> fragmentClass, Class<? extends androidx.fragment.app.strictmode.Violation> violationClass);
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder allowViolation(String fragmentClass, Class<? extends androidx.fragment.app.strictmode.Violation> violationClass);
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy build();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectFragmentReuse();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectFragmentTagUsage();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectRetainInstanceUsage();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectSetUserVisibleHint();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectTargetFragmentUsage();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectWrongFragmentContainer();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyDeath();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyListener(androidx.fragment.app.strictmode.FragmentStrictMode.OnViolationListener listener);
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyLog();
-  }
-
-  public final class FragmentTagUsageViolation extends androidx.fragment.app.strictmode.Violation {
-    method public android.view.ViewGroup? getParentContainer();
-    property public final android.view.ViewGroup? parentContainer;
-  }
-
-  public final class GetRetainInstanceUsageViolation extends androidx.fragment.app.strictmode.RetainInstanceUsageViolation {
-  }
-
-  public final class GetTargetFragmentRequestCodeUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
-  }
-
-  public final class GetTargetFragmentUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
-  }
-
-  public abstract class RetainInstanceUsageViolation extends androidx.fragment.app.strictmode.Violation {
-  }
-
-  public final class SetRetainInstanceUsageViolation extends androidx.fragment.app.strictmode.RetainInstanceUsageViolation {
-  }
-
-  public final class SetTargetFragmentUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
-    method public int getRequestCode();
-    method public androidx.fragment.app.Fragment getTargetFragment();
-    property public final int requestCode;
-    property public final androidx.fragment.app.Fragment targetFragment;
-  }
-
-  public final class SetUserVisibleHintViolation extends androidx.fragment.app.strictmode.Violation {
-    method public boolean isVisibleToUser();
-    property public final boolean isVisibleToUser;
-  }
-
-  public abstract class TargetFragmentUsageViolation extends androidx.fragment.app.strictmode.Violation {
-  }
-
-  public abstract class Violation extends java.lang.RuntimeException {
-    method public final androidx.fragment.app.Fragment getFragment();
-    property public final androidx.fragment.app.Fragment fragment;
-  }
-
-  public final class WrongFragmentContainerViolation extends androidx.fragment.app.strictmode.Violation {
-    method public android.view.ViewGroup getContainer();
-    property public final android.view.ViewGroup container;
-  }
-
-}
-
diff --git a/fragment/fragment/api/public_plus_experimental_1.5.0-beta01.txt b/fragment/fragment/api/public_plus_experimental_1.5.0-beta01.txt
deleted file mode 100644
index 32377c9..0000000
--- a/fragment/fragment/api/public_plus_experimental_1.5.0-beta01.txt
+++ /dev/null
@@ -1,543 +0,0 @@
-// Signature format: 4.0
-package androidx.fragment.app {
-
-  public class DialogFragment extends androidx.fragment.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
-    ctor public DialogFragment();
-    ctor public DialogFragment(@LayoutRes int);
-    method public void dismiss();
-    method public void dismissAllowingStateLoss();
-    method @MainThread public void dismissNow();
-    method public android.app.Dialog? getDialog();
-    method public boolean getShowsDialog();
-    method @StyleRes public int getTheme();
-    method public boolean isCancelable();
-    method public void onCancel(android.content.DialogInterface);
-    method @MainThread public android.app.Dialog onCreateDialog(android.os.Bundle?);
-    method public void onDismiss(android.content.DialogInterface);
-    method public final android.app.Dialog requireDialog();
-    method public void setCancelable(boolean);
-    method public void setShowsDialog(boolean);
-    method public void setStyle(int, @StyleRes int);
-    method public void show(androidx.fragment.app.FragmentManager, String?);
-    method public int show(androidx.fragment.app.FragmentTransaction, String?);
-    method public void showNow(androidx.fragment.app.FragmentManager, String?);
-    field public static final int STYLE_NORMAL = 0; // 0x0
-    field public static final int STYLE_NO_FRAME = 2; // 0x2
-    field public static final int STYLE_NO_INPUT = 3; // 0x3
-    field public static final int STYLE_NO_TITLE = 1; // 0x1
-  }
-
-  public class Fragment implements androidx.activity.result.ActivityResultCaller android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
-    ctor public Fragment();
-    ctor @ContentView public Fragment(@LayoutRes int);
-    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
-    method public final boolean equals(Object?);
-    method public final androidx.fragment.app.FragmentActivity? getActivity();
-    method public boolean getAllowEnterTransitionOverlap();
-    method public boolean getAllowReturnTransitionOverlap();
-    method public final android.os.Bundle? getArguments();
-    method public final androidx.fragment.app.FragmentManager getChildFragmentManager();
-    method public android.content.Context? getContext();
-    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
-    method public Object? getEnterTransition();
-    method public Object? getExitTransition();
-    method @Deprecated public final androidx.fragment.app.FragmentManager? getFragmentManager();
-    method public final Object? getHost();
-    method public final int getId();
-    method public final android.view.LayoutInflater getLayoutInflater();
-    method public androidx.lifecycle.Lifecycle getLifecycle();
-    method @Deprecated public androidx.loader.app.LoaderManager getLoaderManager();
-    method public final androidx.fragment.app.Fragment? getParentFragment();
-    method public final androidx.fragment.app.FragmentManager getParentFragmentManager();
-    method public Object? getReenterTransition();
-    method public final android.content.res.Resources getResources();
-    method @Deprecated public final boolean getRetainInstance();
-    method public Object? getReturnTransition();
-    method public final androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
-    method public Object? getSharedElementEnterTransition();
-    method public Object? getSharedElementReturnTransition();
-    method public final String getString(@StringRes int);
-    method public final String getString(@StringRes int, java.lang.Object!...);
-    method public final String? getTag();
-    method @Deprecated public final androidx.fragment.app.Fragment? getTargetFragment();
-    method @Deprecated public final int getTargetRequestCode();
-    method public final CharSequence getText(@StringRes int);
-    method @Deprecated public boolean getUserVisibleHint();
-    method public android.view.View? getView();
-    method @MainThread public androidx.lifecycle.LifecycleOwner getViewLifecycleOwner();
-    method public androidx.lifecycle.LiveData<androidx.lifecycle.LifecycleOwner!> getViewLifecycleOwnerLiveData();
-    method public androidx.lifecycle.ViewModelStore getViewModelStore();
-    method public final int hashCode();
-    method @Deprecated public static androidx.fragment.app.Fragment instantiate(android.content.Context, String);
-    method @Deprecated public static androidx.fragment.app.Fragment instantiate(android.content.Context, String, android.os.Bundle?);
-    method public final boolean isAdded();
-    method public final boolean isDetached();
-    method public final boolean isHidden();
-    method public final boolean isInLayout();
-    method public final boolean isRemoving();
-    method public final boolean isResumed();
-    method public final boolean isStateSaved();
-    method public final boolean isVisible();
-    method @Deprecated @CallSuper @MainThread public void onActivityCreated(android.os.Bundle?);
-    method @Deprecated public void onActivityResult(int, int, android.content.Intent?);
-    method @CallSuper @MainThread public void onAttach(android.content.Context);
-    method @Deprecated @CallSuper @MainThread public void onAttach(android.app.Activity);
-    method @Deprecated @MainThread public void onAttachFragment(androidx.fragment.app.Fragment);
-    method @CallSuper public void onConfigurationChanged(android.content.res.Configuration);
-    method @MainThread public boolean onContextItemSelected(android.view.MenuItem);
-    method @CallSuper @MainThread public void onCreate(android.os.Bundle?);
-    method @MainThread public android.view.animation.Animation? onCreateAnimation(int, boolean, int);
-    method @MainThread public android.animation.Animator? onCreateAnimator(int, boolean, int);
-    method @MainThread public void onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo?);
-    method @Deprecated @MainThread public void onCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
-    method @MainThread public android.view.View? onCreateView(android.view.LayoutInflater, android.view.ViewGroup?, android.os.Bundle?);
-    method @CallSuper @MainThread public void onDestroy();
-    method @Deprecated @MainThread public void onDestroyOptionsMenu();
-    method @CallSuper @MainThread public void onDestroyView();
-    method @CallSuper @MainThread public void onDetach();
-    method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle?);
-    method @MainThread public void onHiddenChanged(boolean);
-    method @CallSuper @UiThread public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle?);
-    method @Deprecated @CallSuper @UiThread public void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle?);
-    method @CallSuper @MainThread public void onLowMemory();
-    method public void onMultiWindowModeChanged(boolean);
-    method @Deprecated @MainThread public boolean onOptionsItemSelected(android.view.MenuItem);
-    method @Deprecated @MainThread public void onOptionsMenuClosed(android.view.Menu);
-    method @CallSuper @MainThread public void onPause();
-    method public void onPictureInPictureModeChanged(boolean);
-    method @Deprecated @MainThread public void onPrepareOptionsMenu(android.view.Menu);
-    method @MainThread public void onPrimaryNavigationFragmentChanged(boolean);
-    method @Deprecated public void onRequestPermissionsResult(int, String![], int[]);
-    method @CallSuper @MainThread public void onResume();
-    method @MainThread public void onSaveInstanceState(android.os.Bundle);
-    method @CallSuper @MainThread public void onStart();
-    method @CallSuper @MainThread public void onStop();
-    method @MainThread public void onViewCreated(android.view.View, android.os.Bundle?);
-    method @CallSuper @MainThread public void onViewStateRestored(android.os.Bundle?);
-    method public void postponeEnterTransition();
-    method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
-    method @MainThread public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
-    method @MainThread 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 void registerForContextMenu(android.view.View);
-    method @Deprecated public final void requestPermissions(String![], int);
-    method public final androidx.fragment.app.FragmentActivity requireActivity();
-    method public final android.os.Bundle requireArguments();
-    method public final android.content.Context requireContext();
-    method @Deprecated public final androidx.fragment.app.FragmentManager requireFragmentManager();
-    method public final Object requireHost();
-    method public final androidx.fragment.app.Fragment requireParentFragment();
-    method public final android.view.View requireView();
-    method public void setAllowEnterTransitionOverlap(boolean);
-    method public void setAllowReturnTransitionOverlap(boolean);
-    method public void setArguments(android.os.Bundle?);
-    method public void setEnterSharedElementCallback(androidx.core.app.SharedElementCallback?);
-    method public void setEnterTransition(Object?);
-    method public void setExitSharedElementCallback(androidx.core.app.SharedElementCallback?);
-    method public void setExitTransition(Object?);
-    method @Deprecated public void setHasOptionsMenu(boolean);
-    method public void setInitialSavedState(androidx.fragment.app.Fragment.SavedState?);
-    method public void setMenuVisibility(boolean);
-    method public void setReenterTransition(Object?);
-    method @Deprecated public void setRetainInstance(boolean);
-    method public void setReturnTransition(Object?);
-    method public void setSharedElementEnterTransition(Object?);
-    method public void setSharedElementReturnTransition(Object?);
-    method @Deprecated public void setTargetFragment(androidx.fragment.app.Fragment?, int);
-    method @Deprecated public void setUserVisibleHint(boolean);
-    method public boolean shouldShowRequestPermissionRationale(String);
-    method public void startActivity(android.content.Intent!);
-    method public void startActivity(android.content.Intent!, android.os.Bundle?);
-    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, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
-    method public void startPostponedEnterTransition();
-    method public void unregisterForContextMenu(android.view.View);
-  }
-
-  public static class Fragment.InstantiationException extends java.lang.RuntimeException {
-    ctor public Fragment.InstantiationException(String, Exception?);
-  }
-
-  public static class Fragment.SavedState implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<androidx.fragment.app.Fragment.SavedState!> CREATOR;
-  }
-
-  public class FragmentActivity extends androidx.activity.ComponentActivity implements androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback androidx.lifecycle.LifecycleOwner {
-    ctor public FragmentActivity();
-    ctor @ContentView public FragmentActivity(@LayoutRes int);
-    method public androidx.fragment.app.FragmentManager getSupportFragmentManager();
-    method @Deprecated public androidx.loader.app.LoaderManager getSupportLoaderManager();
-    method @Deprecated @MainThread public void onAttachFragment(androidx.fragment.app.Fragment);
-    method protected void onResumeFragments();
-    method public void onStateNotSaved();
-    method public void setEnterSharedElementCallback(androidx.core.app.SharedElementCallback?);
-    method public void setExitSharedElementCallback(androidx.core.app.SharedElementCallback?);
-    method public void startActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int);
-    method public void startActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int, android.os.Bundle?);
-    method @Deprecated public void startIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
-    method public void supportFinishAfterTransition();
-    method @Deprecated public void supportInvalidateOptionsMenu();
-    method public void supportPostponeEnterTransition();
-    method public void supportStartPostponedEnterTransition();
-    method @Deprecated public final void validateRequestPermissionsRequestCode(int);
-  }
-
-  public abstract class FragmentContainer {
-    ctor public FragmentContainer();
-    method @Deprecated public androidx.fragment.app.Fragment instantiate(android.content.Context, String, android.os.Bundle?);
-    method public abstract android.view.View? onFindViewById(@IdRes int);
-    method public abstract boolean onHasView();
-  }
-
-  public final class FragmentContainerView extends android.widget.FrameLayout {
-    ctor public FragmentContainerView(android.content.Context context);
-    ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
-    ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
-    method public <F extends androidx.fragment.app.Fragment> F! getFragment();
-  }
-
-  public class FragmentController {
-    method public void attachHost(androidx.fragment.app.Fragment?);
-    method public static androidx.fragment.app.FragmentController createController(androidx.fragment.app.FragmentHostCallback<?>);
-    method public void dispatchActivityCreated();
-    method @Deprecated public void dispatchConfigurationChanged(android.content.res.Configuration);
-    method public boolean dispatchContextItemSelected(android.view.MenuItem);
-    method public void dispatchCreate();
-    method @Deprecated public boolean dispatchCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
-    method public void dispatchDestroy();
-    method public void dispatchDestroyView();
-    method @Deprecated public void dispatchLowMemory();
-    method @Deprecated public void dispatchMultiWindowModeChanged(boolean);
-    method @Deprecated public boolean dispatchOptionsItemSelected(android.view.MenuItem);
-    method @Deprecated public void dispatchOptionsMenuClosed(android.view.Menu);
-    method public void dispatchPause();
-    method @Deprecated public void dispatchPictureInPictureModeChanged(boolean);
-    method @Deprecated public boolean dispatchPrepareOptionsMenu(android.view.Menu);
-    method @Deprecated public void dispatchReallyStop();
-    method public void dispatchResume();
-    method public void dispatchStart();
-    method public void dispatchStop();
-    method @Deprecated public void doLoaderDestroy();
-    method @Deprecated public void doLoaderRetain();
-    method @Deprecated public void doLoaderStart();
-    method @Deprecated public void doLoaderStop(boolean);
-    method @Deprecated public void dumpLoaders(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
-    method public boolean execPendingActions();
-    method public androidx.fragment.app.Fragment? findFragmentByWho(String);
-    method public java.util.List<androidx.fragment.app.Fragment!> getActiveFragments(java.util.List<androidx.fragment.app.Fragment!>!);
-    method public int getActiveFragmentsCount();
-    method public androidx.fragment.app.FragmentManager getSupportFragmentManager();
-    method @Deprecated public androidx.loader.app.LoaderManager! getSupportLoaderManager();
-    method public void noteStateNotSaved();
-    method public android.view.View? onCreateView(android.view.View?, String, android.content.Context, android.util.AttributeSet);
-    method @Deprecated public void reportLoaderStart();
-    method @Deprecated public void restoreAllState(android.os.Parcelable?, java.util.List<androidx.fragment.app.Fragment!>?);
-    method @Deprecated public void restoreAllState(android.os.Parcelable?, androidx.fragment.app.FragmentManagerNonConfig?);
-    method @Deprecated public void restoreLoaderNonConfig(androidx.collection.SimpleArrayMap<java.lang.String!,androidx.loader.app.LoaderManager!>!);
-    method @Deprecated public void restoreSaveState(android.os.Parcelable?);
-    method @Deprecated public androidx.collection.SimpleArrayMap<java.lang.String!,androidx.loader.app.LoaderManager!>? retainLoaderNonConfig();
-    method @Deprecated public androidx.fragment.app.FragmentManagerNonConfig? retainNestedNonConfig();
-    method @Deprecated public java.util.List<androidx.fragment.app.Fragment!>? retainNonConfig();
-    method @Deprecated public android.os.Parcelable? saveAllState();
-  }
-
-  public class FragmentFactory {
-    ctor public FragmentFactory();
-    method public androidx.fragment.app.Fragment instantiate(ClassLoader, String);
-    method public static Class<? extends androidx.fragment.app.Fragment> loadFragmentClass(ClassLoader, String);
-  }
-
-  public abstract class FragmentHostCallback<E> extends androidx.fragment.app.FragmentContainer {
-    ctor public FragmentHostCallback(android.content.Context, android.os.Handler, int);
-    method public void onDump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
-    method public android.view.View? onFindViewById(int);
-    method public abstract E? onGetHost();
-    method public android.view.LayoutInflater onGetLayoutInflater();
-    method public int onGetWindowAnimations();
-    method public boolean onHasView();
-    method public boolean onHasWindowAnimations();
-    method @Deprecated public void onRequestPermissionsFromFragment(androidx.fragment.app.Fragment, String![], int);
-    method public boolean onShouldSaveFragmentState(androidx.fragment.app.Fragment);
-    method public boolean onShouldShowRequestPermissionRationale(String);
-    method public void onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int);
-    method public void onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int, android.os.Bundle?);
-    method @Deprecated public void onStartIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
-    method public void onSupportInvalidateOptionsMenu();
-  }
-
-  public abstract class FragmentManager implements androidx.fragment.app.FragmentResultOwner {
-    ctor public FragmentManager();
-    method public void addFragmentOnAttachListener(androidx.fragment.app.FragmentOnAttachListener);
-    method public void addOnBackStackChangedListener(androidx.fragment.app.FragmentManager.OnBackStackChangedListener);
-    method public androidx.fragment.app.FragmentTransaction beginTransaction();
-    method public void clearBackStack(String);
-    method public final void clearFragmentResult(String);
-    method public final void clearFragmentResultListener(String);
-    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
-    method @Deprecated public static void enableDebugLogging(boolean);
-    method public boolean executePendingTransactions();
-    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
-    method public androidx.fragment.app.Fragment? findFragmentById(@IdRes int);
-    method public androidx.fragment.app.Fragment? findFragmentByTag(String?);
-    method public androidx.fragment.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
-    method public int getBackStackEntryCount();
-    method public androidx.fragment.app.Fragment? getFragment(android.os.Bundle, String);
-    method public androidx.fragment.app.FragmentFactory getFragmentFactory();
-    method public java.util.List<androidx.fragment.app.Fragment!> getFragments();
-    method public androidx.fragment.app.Fragment? getPrimaryNavigationFragment();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy? getStrictModePolicy();
-    method public boolean isDestroyed();
-    method public boolean isStateSaved();
-    method public void popBackStack();
-    method public void popBackStack(String?, int);
-    method public void popBackStack(int, int);
-    method public boolean popBackStackImmediate();
-    method public boolean popBackStackImmediate(String?, int);
-    method public boolean popBackStackImmediate(int, int);
-    method public void putFragment(android.os.Bundle, String, androidx.fragment.app.Fragment);
-    method public void registerFragmentLifecycleCallbacks(androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks, boolean);
-    method public void removeFragmentOnAttachListener(androidx.fragment.app.FragmentOnAttachListener);
-    method public void removeOnBackStackChangedListener(androidx.fragment.app.FragmentManager.OnBackStackChangedListener);
-    method public void restoreBackStack(String);
-    method public void saveBackStack(String);
-    method public androidx.fragment.app.Fragment.SavedState? saveFragmentInstanceState(androidx.fragment.app.Fragment);
-    method public void setFragmentFactory(androidx.fragment.app.FragmentFactory);
-    method public final void setFragmentResult(String, android.os.Bundle);
-    method public final void setFragmentResultListener(String, androidx.lifecycle.LifecycleOwner, androidx.fragment.app.FragmentResultListener);
-    method public void setStrictModePolicy(androidx.fragment.app.strictmode.FragmentStrictMode.Policy?);
-    method public void unregisterFragmentLifecycleCallbacks(androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks);
-    field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
-  }
-
-  public static interface FragmentManager.BackStackEntry {
-    method @Deprecated public CharSequence? getBreadCrumbShortTitle();
-    method @Deprecated @StringRes public int getBreadCrumbShortTitleRes();
-    method @Deprecated public CharSequence? getBreadCrumbTitle();
-    method @Deprecated @StringRes public int getBreadCrumbTitleRes();
-    method public int getId();
-    method public String? getName();
-  }
-
-  public abstract static class FragmentManager.FragmentLifecycleCallbacks {
-    ctor public FragmentManager.FragmentLifecycleCallbacks();
-    method @Deprecated public void onFragmentActivityCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
-    method public void onFragmentAttached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.content.Context);
-    method public void onFragmentCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
-    method public void onFragmentDestroyed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentDetached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentPaused(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentPreAttached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.content.Context);
-    method public void onFragmentPreCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
-    method public void onFragmentResumed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentSaveInstanceState(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle);
-    method public void onFragmentStarted(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentStopped(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentViewCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.view.View, android.os.Bundle?);
-    method public void onFragmentViewDestroyed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-  }
-
-  public static interface FragmentManager.OnBackStackChangedListener {
-    method @MainThread public void onBackStackChanged();
-  }
-
-  @Deprecated public class FragmentManagerNonConfig {
-  }
-
-  public interface FragmentOnAttachListener {
-    method @MainThread public void onAttachFragment(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-  }
-
-  @Deprecated public abstract class FragmentPagerAdapter extends androidx.viewpager.widget.PagerAdapter {
-    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager);
-    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager, int);
-    method @Deprecated public abstract androidx.fragment.app.Fragment getItem(int);
-    method @Deprecated public long getItemId(int);
-    method @Deprecated public boolean isViewFromObject(android.view.View, Object);
-    field @Deprecated public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1; // 0x1
-    field @Deprecated public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0; // 0x0
-  }
-
-  public interface FragmentResultListener {
-    method public void onFragmentResult(String, android.os.Bundle);
-  }
-
-  public interface FragmentResultOwner {
-    method public void clearFragmentResult(String);
-    method public void clearFragmentResultListener(String);
-    method public void setFragmentResult(String, android.os.Bundle);
-    method public void setFragmentResultListener(String, androidx.lifecycle.LifecycleOwner, androidx.fragment.app.FragmentResultListener);
-  }
-
-  @Deprecated public abstract class FragmentStatePagerAdapter extends androidx.viewpager.widget.PagerAdapter {
-    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager);
-    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager, int);
-    method @Deprecated public abstract androidx.fragment.app.Fragment getItem(int);
-    method @Deprecated public boolean isViewFromObject(android.view.View, Object);
-    field @Deprecated public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1; // 0x1
-    field @Deprecated public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0; // 0x0
-  }
-
-  @Deprecated public class FragmentTabHost extends android.widget.TabHost implements android.widget.TabHost.OnTabChangeListener {
-    ctor @Deprecated public FragmentTabHost(android.content.Context);
-    ctor @Deprecated public FragmentTabHost(android.content.Context, android.util.AttributeSet?);
-    method @Deprecated public void addTab(android.widget.TabHost.TabSpec, Class<?>, android.os.Bundle?);
-    method @Deprecated public void onTabChanged(String?);
-    method @Deprecated public void setup(android.content.Context, androidx.fragment.app.FragmentManager);
-    method @Deprecated public void setup(android.content.Context, androidx.fragment.app.FragmentManager, int);
-  }
-
-  public abstract class FragmentTransaction {
-    ctor @Deprecated public FragmentTransaction();
-    method public final androidx.fragment.app.FragmentTransaction add(Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
-    method public androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.Fragment, String?);
-    method public final androidx.fragment.app.FragmentTransaction add(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?);
-    method public androidx.fragment.app.FragmentTransaction add(@IdRes int, androidx.fragment.app.Fragment);
-    method public final androidx.fragment.app.FragmentTransaction add(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
-    method public androidx.fragment.app.FragmentTransaction add(@IdRes int, androidx.fragment.app.Fragment, String?);
-    method public androidx.fragment.app.FragmentTransaction addSharedElement(android.view.View, String);
-    method public androidx.fragment.app.FragmentTransaction addToBackStack(String?);
-    method public androidx.fragment.app.FragmentTransaction attach(androidx.fragment.app.Fragment);
-    method public abstract int commit();
-    method public abstract int commitAllowingStateLoss();
-    method public abstract void commitNow();
-    method public abstract void commitNowAllowingStateLoss();
-    method public androidx.fragment.app.FragmentTransaction detach(androidx.fragment.app.Fragment);
-    method public androidx.fragment.app.FragmentTransaction disallowAddToBackStack();
-    method public androidx.fragment.app.FragmentTransaction hide(androidx.fragment.app.Fragment);
-    method public boolean isAddToBackStackAllowed();
-    method public boolean isEmpty();
-    method public androidx.fragment.app.FragmentTransaction remove(androidx.fragment.app.Fragment);
-    method public final androidx.fragment.app.FragmentTransaction replace(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?);
-    method public androidx.fragment.app.FragmentTransaction replace(@IdRes int, androidx.fragment.app.Fragment);
-    method public final androidx.fragment.app.FragmentTransaction replace(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
-    method public androidx.fragment.app.FragmentTransaction replace(@IdRes int, androidx.fragment.app.Fragment, String?);
-    method public androidx.fragment.app.FragmentTransaction runOnCommit(Runnable);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setAllowOptimization(boolean);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbShortTitle(@StringRes int);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbShortTitle(CharSequence?);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbTitle(@StringRes int);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbTitle(CharSequence?);
-    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int);
-    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int);
-    method public androidx.fragment.app.FragmentTransaction setMaxLifecycle(androidx.fragment.app.Fragment, androidx.lifecycle.Lifecycle.State);
-    method public androidx.fragment.app.FragmentTransaction setPrimaryNavigationFragment(androidx.fragment.app.Fragment?);
-    method public androidx.fragment.app.FragmentTransaction setReorderingAllowed(boolean);
-    method public androidx.fragment.app.FragmentTransaction setTransition(int);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setTransitionStyle(@StyleRes int);
-    method public androidx.fragment.app.FragmentTransaction show(androidx.fragment.app.Fragment);
-    field public static final int TRANSIT_ENTER_MASK = 4096; // 0x1000
-    field public static final int TRANSIT_EXIT_MASK = 8192; // 0x2000
-    field public static final int TRANSIT_FRAGMENT_CLOSE = 8194; // 0x2002
-    field public static final int TRANSIT_FRAGMENT_FADE = 4099; // 0x1003
-    field public static final int TRANSIT_FRAGMENT_MATCH_ACTIVITY_CLOSE = 8197; // 0x2005
-    field public static final int TRANSIT_FRAGMENT_MATCH_ACTIVITY_OPEN = 4100; // 0x1004
-    field public static final int TRANSIT_FRAGMENT_OPEN = 4097; // 0x1001
-    field public static final int TRANSIT_NONE = 0; // 0x0
-    field public static final int TRANSIT_UNSET = -1; // 0xffffffff
-  }
-
-  public class ListFragment extends androidx.fragment.app.Fragment {
-    ctor public ListFragment();
-    method public android.widget.ListAdapter? getListAdapter();
-    method public android.widget.ListView getListView();
-    method public long getSelectedItemId();
-    method public int getSelectedItemPosition();
-    method public void onListItemClick(android.widget.ListView, android.view.View, int, long);
-    method public final android.widget.ListAdapter requireListAdapter();
-    method public void setEmptyText(CharSequence?);
-    method public void setListAdapter(android.widget.ListAdapter?);
-    method public void setListShown(boolean);
-    method public void setListShownNoAnimation(boolean);
-    method public void setSelection(int);
-  }
-
-}
-
-package androidx.fragment.app.strictmode {
-
-  public final class FragmentReuseViolation extends androidx.fragment.app.strictmode.Violation {
-    method public String getPreviousFragmentId();
-    property public final String previousFragmentId;
-  }
-
-  public final class FragmentStrictMode {
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy getDefaultPolicy();
-    method @VisibleForTesting public void onPolicyViolation(androidx.fragment.app.strictmode.Violation violation);
-    method public void setDefaultPolicy(androidx.fragment.app.strictmode.FragmentStrictMode.Policy);
-    property public final androidx.fragment.app.strictmode.FragmentStrictMode.Policy defaultPolicy;
-    field public static final androidx.fragment.app.strictmode.FragmentStrictMode INSTANCE;
-  }
-
-  public static fun interface FragmentStrictMode.OnViolationListener {
-    method public void onViolation(androidx.fragment.app.strictmode.Violation violation);
-  }
-
-  public static final class FragmentStrictMode.Policy {
-    field public static final androidx.fragment.app.strictmode.FragmentStrictMode.Policy LAX;
-  }
-
-  public static final class FragmentStrictMode.Policy.Builder {
-    ctor public FragmentStrictMode.Policy.Builder();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder allowViolation(Class<? extends androidx.fragment.app.Fragment> fragmentClass, Class<? extends androidx.fragment.app.strictmode.Violation> violationClass);
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder allowViolation(String fragmentClass, Class<? extends androidx.fragment.app.strictmode.Violation> violationClass);
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy build();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectFragmentReuse();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectFragmentTagUsage();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectRetainInstanceUsage();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectSetUserVisibleHint();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectTargetFragmentUsage();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectWrongFragmentContainer();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyDeath();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyListener(androidx.fragment.app.strictmode.FragmentStrictMode.OnViolationListener listener);
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyLog();
-  }
-
-  public final class FragmentTagUsageViolation extends androidx.fragment.app.strictmode.Violation {
-    method public android.view.ViewGroup? getParentContainer();
-    property public final android.view.ViewGroup? parentContainer;
-  }
-
-  public final class GetRetainInstanceUsageViolation extends androidx.fragment.app.strictmode.RetainInstanceUsageViolation {
-  }
-
-  public final class GetTargetFragmentRequestCodeUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
-  }
-
-  public final class GetTargetFragmentUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
-  }
-
-  public abstract class RetainInstanceUsageViolation extends androidx.fragment.app.strictmode.Violation {
-  }
-
-  public final class SetRetainInstanceUsageViolation extends androidx.fragment.app.strictmode.RetainInstanceUsageViolation {
-  }
-
-  public final class SetTargetFragmentUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
-    method public int getRequestCode();
-    method public androidx.fragment.app.Fragment getTargetFragment();
-    property public final int requestCode;
-    property public final androidx.fragment.app.Fragment targetFragment;
-  }
-
-  public final class SetUserVisibleHintViolation extends androidx.fragment.app.strictmode.Violation {
-    method public boolean isVisibleToUser();
-    property public final boolean isVisibleToUser;
-  }
-
-  public abstract class TargetFragmentUsageViolation extends androidx.fragment.app.strictmode.Violation {
-  }
-
-  public abstract class Violation extends java.lang.RuntimeException {
-    method public final androidx.fragment.app.Fragment getFragment();
-    property public final androidx.fragment.app.Fragment fragment;
-  }
-
-  public final class WrongFragmentContainerViolation extends androidx.fragment.app.strictmode.Violation {
-    method public android.view.ViewGroup getContainer();
-    property public final android.view.ViewGroup container;
-  }
-
-}
-
diff --git a/fragment/fragment/api/res-1.5.0-beta01.txt b/fragment/fragment/api/res-1.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/fragment/fragment/api/res-1.5.0-beta01.txt
+++ /dev/null
diff --git a/fragment/fragment/api/restricted_1.5.0-beta01.txt b/fragment/fragment/api/restricted_1.5.0-beta01.txt
deleted file mode 100644
index 7f0aa7c..0000000
--- a/fragment/fragment/api/restricted_1.5.0-beta01.txt
+++ /dev/null
@@ -1,572 +0,0 @@
-// Signature format: 4.0
-package androidx.fragment.app {
-
-  public class DialogFragment extends androidx.fragment.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
-    ctor public DialogFragment();
-    ctor public DialogFragment(@LayoutRes int);
-    method public void dismiss();
-    method public void dismissAllowingStateLoss();
-    method @MainThread public void dismissNow();
-    method public android.app.Dialog? getDialog();
-    method public boolean getShowsDialog();
-    method @StyleRes public int getTheme();
-    method public boolean isCancelable();
-    method public void onCancel(android.content.DialogInterface);
-    method @MainThread public android.app.Dialog onCreateDialog(android.os.Bundle?);
-    method public void onDismiss(android.content.DialogInterface);
-    method public final android.app.Dialog requireDialog();
-    method public void setCancelable(boolean);
-    method public void setShowsDialog(boolean);
-    method public void setStyle(int, @StyleRes int);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void setupDialog(android.app.Dialog, int);
-    method public void show(androidx.fragment.app.FragmentManager, String?);
-    method public int show(androidx.fragment.app.FragmentTransaction, String?);
-    method public void showNow(androidx.fragment.app.FragmentManager, String?);
-    field public static final int STYLE_NORMAL = 0; // 0x0
-    field public static final int STYLE_NO_FRAME = 2; // 0x2
-    field public static final int STYLE_NO_INPUT = 3; // 0x3
-    field public static final int STYLE_NO_TITLE = 1; // 0x1
-  }
-
-  public class Fragment implements androidx.activity.result.ActivityResultCaller android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
-    ctor public Fragment();
-    ctor @ContentView public Fragment(@LayoutRes int);
-    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
-    method public final boolean equals(Object?);
-    method public final androidx.fragment.app.FragmentActivity? getActivity();
-    method public boolean getAllowEnterTransitionOverlap();
-    method public boolean getAllowReturnTransitionOverlap();
-    method public final android.os.Bundle? getArguments();
-    method public final androidx.fragment.app.FragmentManager getChildFragmentManager();
-    method public android.content.Context? getContext();
-    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
-    method public Object? getEnterTransition();
-    method public Object? getExitTransition();
-    method @Deprecated public final androidx.fragment.app.FragmentManager? getFragmentManager();
-    method public final Object? getHost();
-    method public final int getId();
-    method public final android.view.LayoutInflater getLayoutInflater();
-    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public android.view.LayoutInflater getLayoutInflater(android.os.Bundle?);
-    method public androidx.lifecycle.Lifecycle getLifecycle();
-    method @Deprecated public androidx.loader.app.LoaderManager getLoaderManager();
-    method public final androidx.fragment.app.Fragment? getParentFragment();
-    method public final androidx.fragment.app.FragmentManager getParentFragmentManager();
-    method public Object? getReenterTransition();
-    method public final android.content.res.Resources getResources();
-    method @Deprecated public final boolean getRetainInstance();
-    method public Object? getReturnTransition();
-    method public final androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
-    method public Object? getSharedElementEnterTransition();
-    method public Object? getSharedElementReturnTransition();
-    method public final String getString(@StringRes int);
-    method public final String getString(@StringRes int, java.lang.Object!...);
-    method public final String? getTag();
-    method @Deprecated public final androidx.fragment.app.Fragment? getTargetFragment();
-    method @Deprecated public final int getTargetRequestCode();
-    method public final CharSequence getText(@StringRes int);
-    method @Deprecated public boolean getUserVisibleHint();
-    method public android.view.View? getView();
-    method @MainThread public androidx.lifecycle.LifecycleOwner getViewLifecycleOwner();
-    method public androidx.lifecycle.LiveData<androidx.lifecycle.LifecycleOwner!> getViewLifecycleOwnerLiveData();
-    method public androidx.lifecycle.ViewModelStore getViewModelStore();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final boolean hasOptionsMenu();
-    method public final int hashCode();
-    method @Deprecated public static androidx.fragment.app.Fragment instantiate(android.content.Context, String);
-    method @Deprecated public static androidx.fragment.app.Fragment instantiate(android.content.Context, String, android.os.Bundle?);
-    method public final boolean isAdded();
-    method public final boolean isDetached();
-    method public final boolean isHidden();
-    method public final boolean isInLayout();
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final boolean isMenuVisible();
-    method public final boolean isRemoving();
-    method public final boolean isResumed();
-    method public final boolean isStateSaved();
-    method public final boolean isVisible();
-    method @Deprecated @CallSuper @MainThread public void onActivityCreated(android.os.Bundle?);
-    method @Deprecated public void onActivityResult(int, int, android.content.Intent?);
-    method @CallSuper @MainThread public void onAttach(android.content.Context);
-    method @Deprecated @CallSuper @MainThread public void onAttach(android.app.Activity);
-    method @Deprecated @MainThread public void onAttachFragment(androidx.fragment.app.Fragment);
-    method @CallSuper public void onConfigurationChanged(android.content.res.Configuration);
-    method @MainThread public boolean onContextItemSelected(android.view.MenuItem);
-    method @CallSuper @MainThread public void onCreate(android.os.Bundle?);
-    method @MainThread public android.view.animation.Animation? onCreateAnimation(int, boolean, int);
-    method @MainThread public android.animation.Animator? onCreateAnimator(int, boolean, int);
-    method @MainThread public void onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo?);
-    method @Deprecated @MainThread public void onCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
-    method @MainThread public android.view.View? onCreateView(android.view.LayoutInflater, android.view.ViewGroup?, android.os.Bundle?);
-    method @CallSuper @MainThread public void onDestroy();
-    method @Deprecated @MainThread public void onDestroyOptionsMenu();
-    method @CallSuper @MainThread public void onDestroyView();
-    method @CallSuper @MainThread public void onDetach();
-    method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle?);
-    method @MainThread public void onHiddenChanged(boolean);
-    method @CallSuper @UiThread public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle?);
-    method @Deprecated @CallSuper @UiThread public void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle?);
-    method @CallSuper @MainThread public void onLowMemory();
-    method public void onMultiWindowModeChanged(boolean);
-    method @Deprecated @MainThread public boolean onOptionsItemSelected(android.view.MenuItem);
-    method @Deprecated @MainThread public void onOptionsMenuClosed(android.view.Menu);
-    method @CallSuper @MainThread public void onPause();
-    method public void onPictureInPictureModeChanged(boolean);
-    method @Deprecated @MainThread public void onPrepareOptionsMenu(android.view.Menu);
-    method @MainThread public void onPrimaryNavigationFragmentChanged(boolean);
-    method @Deprecated public void onRequestPermissionsResult(int, String![], int[]);
-    method @CallSuper @MainThread public void onResume();
-    method @MainThread public void onSaveInstanceState(android.os.Bundle);
-    method @CallSuper @MainThread public void onStart();
-    method @CallSuper @MainThread public void onStop();
-    method @MainThread public void onViewCreated(android.view.View, android.os.Bundle?);
-    method @CallSuper @MainThread public void onViewStateRestored(android.os.Bundle?);
-    method public void postponeEnterTransition();
-    method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
-    method @MainThread public final <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerForActivityResult(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
-    method @MainThread 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 void registerForContextMenu(android.view.View);
-    method @Deprecated public final void requestPermissions(String![], int);
-    method public final androidx.fragment.app.FragmentActivity requireActivity();
-    method public final android.os.Bundle requireArguments();
-    method public final android.content.Context requireContext();
-    method @Deprecated public final androidx.fragment.app.FragmentManager requireFragmentManager();
-    method public final Object requireHost();
-    method public final androidx.fragment.app.Fragment requireParentFragment();
-    method public final android.view.View requireView();
-    method public void setAllowEnterTransitionOverlap(boolean);
-    method public void setAllowReturnTransitionOverlap(boolean);
-    method public void setArguments(android.os.Bundle?);
-    method public void setEnterSharedElementCallback(androidx.core.app.SharedElementCallback?);
-    method public void setEnterTransition(Object?);
-    method public void setExitSharedElementCallback(androidx.core.app.SharedElementCallback?);
-    method public void setExitTransition(Object?);
-    method @Deprecated public void setHasOptionsMenu(boolean);
-    method public void setInitialSavedState(androidx.fragment.app.Fragment.SavedState?);
-    method public void setMenuVisibility(boolean);
-    method public void setReenterTransition(Object?);
-    method @Deprecated public void setRetainInstance(boolean);
-    method public void setReturnTransition(Object?);
-    method public void setSharedElementEnterTransition(Object?);
-    method public void setSharedElementReturnTransition(Object?);
-    method @Deprecated public void setTargetFragment(androidx.fragment.app.Fragment?, int);
-    method @Deprecated public void setUserVisibleHint(boolean);
-    method public boolean shouldShowRequestPermissionRationale(String);
-    method public void startActivity(android.content.Intent!);
-    method public void startActivity(android.content.Intent!, android.os.Bundle?);
-    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, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
-    method public void startPostponedEnterTransition();
-    method public void unregisterForContextMenu(android.view.View);
-  }
-
-  public static class Fragment.InstantiationException extends java.lang.RuntimeException {
-    ctor public Fragment.InstantiationException(String, Exception?);
-  }
-
-  public static class Fragment.SavedState implements android.os.Parcelable {
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<androidx.fragment.app.Fragment.SavedState!> CREATOR;
-  }
-
-  public class FragmentActivity extends androidx.activity.ComponentActivity implements androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback androidx.core.app.ActivityCompat.RequestPermissionsRequestCodeValidator {
-    ctor public FragmentActivity();
-    ctor @ContentView public FragmentActivity(@LayoutRes int);
-    method public androidx.fragment.app.FragmentManager getSupportFragmentManager();
-    method @Deprecated public androidx.loader.app.LoaderManager getSupportLoaderManager();
-    method @Deprecated @MainThread public void onAttachFragment(androidx.fragment.app.Fragment);
-    method protected void onResumeFragments();
-    method public void onStateNotSaved();
-    method public void setEnterSharedElementCallback(androidx.core.app.SharedElementCallback?);
-    method public void setExitSharedElementCallback(androidx.core.app.SharedElementCallback?);
-    method public void startActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int);
-    method public void startActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int, android.os.Bundle?);
-    method @Deprecated public void startIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
-    method public void supportFinishAfterTransition();
-    method @Deprecated public void supportInvalidateOptionsMenu();
-    method public void supportPostponeEnterTransition();
-    method public void supportStartPostponedEnterTransition();
-    method @Deprecated public final void validateRequestPermissionsRequestCode(int);
-  }
-
-  public abstract class FragmentContainer {
-    ctor public FragmentContainer();
-    method @Deprecated public androidx.fragment.app.Fragment instantiate(android.content.Context, String, android.os.Bundle?);
-    method public abstract android.view.View? onFindViewById(@IdRes int);
-    method public abstract boolean onHasView();
-  }
-
-  public final class FragmentContainerView extends android.widget.FrameLayout {
-    ctor public FragmentContainerView(android.content.Context context);
-    ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs, optional int defStyleAttr);
-    ctor public FragmentContainerView(android.content.Context context, android.util.AttributeSet? attrs);
-    method public <F extends androidx.fragment.app.Fragment> F! getFragment();
-  }
-
-  public class FragmentController {
-    method public void attachHost(androidx.fragment.app.Fragment?);
-    method public static androidx.fragment.app.FragmentController createController(androidx.fragment.app.FragmentHostCallback<?>);
-    method public void dispatchActivityCreated();
-    method @Deprecated public void dispatchConfigurationChanged(android.content.res.Configuration);
-    method public boolean dispatchContextItemSelected(android.view.MenuItem);
-    method public void dispatchCreate();
-    method @Deprecated public boolean dispatchCreateOptionsMenu(android.view.Menu, android.view.MenuInflater);
-    method public void dispatchDestroy();
-    method public void dispatchDestroyView();
-    method @Deprecated public void dispatchLowMemory();
-    method @Deprecated public void dispatchMultiWindowModeChanged(boolean);
-    method @Deprecated public boolean dispatchOptionsItemSelected(android.view.MenuItem);
-    method @Deprecated public void dispatchOptionsMenuClosed(android.view.Menu);
-    method public void dispatchPause();
-    method @Deprecated public void dispatchPictureInPictureModeChanged(boolean);
-    method @Deprecated public boolean dispatchPrepareOptionsMenu(android.view.Menu);
-    method @Deprecated public void dispatchReallyStop();
-    method public void dispatchResume();
-    method public void dispatchStart();
-    method public void dispatchStop();
-    method @Deprecated public void doLoaderDestroy();
-    method @Deprecated public void doLoaderRetain();
-    method @Deprecated public void doLoaderStart();
-    method @Deprecated public void doLoaderStop(boolean);
-    method @Deprecated public void dumpLoaders(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
-    method public boolean execPendingActions();
-    method public androidx.fragment.app.Fragment? findFragmentByWho(String);
-    method public java.util.List<androidx.fragment.app.Fragment!> getActiveFragments(java.util.List<androidx.fragment.app.Fragment!>!);
-    method public int getActiveFragmentsCount();
-    method public androidx.fragment.app.FragmentManager getSupportFragmentManager();
-    method @Deprecated public androidx.loader.app.LoaderManager! getSupportLoaderManager();
-    method public void noteStateNotSaved();
-    method public android.view.View? onCreateView(android.view.View?, String, android.content.Context, android.util.AttributeSet);
-    method @Deprecated public void reportLoaderStart();
-    method @Deprecated public void restoreAllState(android.os.Parcelable?, java.util.List<androidx.fragment.app.Fragment!>?);
-    method @Deprecated public void restoreAllState(android.os.Parcelable?, androidx.fragment.app.FragmentManagerNonConfig?);
-    method @Deprecated public void restoreLoaderNonConfig(androidx.collection.SimpleArrayMap<java.lang.String!,androidx.loader.app.LoaderManager!>!);
-    method @Deprecated public void restoreSaveState(android.os.Parcelable?);
-    method @Deprecated public androidx.collection.SimpleArrayMap<java.lang.String!,androidx.loader.app.LoaderManager!>? retainLoaderNonConfig();
-    method @Deprecated public androidx.fragment.app.FragmentManagerNonConfig? retainNestedNonConfig();
-    method @Deprecated public java.util.List<androidx.fragment.app.Fragment!>? retainNonConfig();
-    method @Deprecated public android.os.Parcelable? saveAllState();
-  }
-
-  public class FragmentFactory {
-    ctor public FragmentFactory();
-    method public androidx.fragment.app.Fragment instantiate(ClassLoader, String);
-    method public static Class<? extends androidx.fragment.app.Fragment> loadFragmentClass(ClassLoader, String);
-  }
-
-  public abstract class FragmentHostCallback<E> extends androidx.fragment.app.FragmentContainer {
-    ctor public FragmentHostCallback(android.content.Context, android.os.Handler, int);
-    method public void onDump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
-    method public android.view.View? onFindViewById(int);
-    method public abstract E? onGetHost();
-    method public android.view.LayoutInflater onGetLayoutInflater();
-    method public int onGetWindowAnimations();
-    method public boolean onHasView();
-    method public boolean onHasWindowAnimations();
-    method @Deprecated public void onRequestPermissionsFromFragment(androidx.fragment.app.Fragment, String![], int);
-    method public boolean onShouldSaveFragmentState(androidx.fragment.app.Fragment);
-    method public boolean onShouldShowRequestPermissionRationale(String);
-    method public void onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int);
-    method public void onStartActivityFromFragment(androidx.fragment.app.Fragment, android.content.Intent!, int, android.os.Bundle?);
-    method @Deprecated public void onStartIntentSenderFromFragment(androidx.fragment.app.Fragment, android.content.IntentSender!, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
-    method public void onSupportInvalidateOptionsMenu();
-  }
-
-  public abstract class FragmentManager implements androidx.fragment.app.FragmentResultOwner {
-    ctor public FragmentManager();
-    method public void addFragmentOnAttachListener(androidx.fragment.app.FragmentOnAttachListener);
-    method public void addOnBackStackChangedListener(androidx.fragment.app.FragmentManager.OnBackStackChangedListener);
-    method public androidx.fragment.app.FragmentTransaction beginTransaction();
-    method public void clearBackStack(String);
-    method public final void clearFragmentResult(String);
-    method public final void clearFragmentResultListener(String);
-    method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
-    method @Deprecated public static void enableDebugLogging(boolean);
-    method public boolean executePendingTransactions();
-    method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
-    method public androidx.fragment.app.Fragment? findFragmentById(@IdRes int);
-    method public androidx.fragment.app.Fragment? findFragmentByTag(String?);
-    method public androidx.fragment.app.FragmentManager.BackStackEntry getBackStackEntryAt(int);
-    method public int getBackStackEntryCount();
-    method public androidx.fragment.app.Fragment? getFragment(android.os.Bundle, String);
-    method public androidx.fragment.app.FragmentFactory getFragmentFactory();
-    method public java.util.List<androidx.fragment.app.Fragment!> getFragments();
-    method public androidx.fragment.app.Fragment? getPrimaryNavigationFragment();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy? getStrictModePolicy();
-    method public boolean isDestroyed();
-    method public boolean isStateSaved();
-    method @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public androidx.fragment.app.FragmentTransaction openTransaction();
-    method public void popBackStack();
-    method public void popBackStack(String?, int);
-    method public void popBackStack(int, int);
-    method public boolean popBackStackImmediate();
-    method public boolean popBackStackImmediate(String?, int);
-    method public boolean popBackStackImmediate(int, int);
-    method public void putFragment(android.os.Bundle, String, androidx.fragment.app.Fragment);
-    method public void registerFragmentLifecycleCallbacks(androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks, boolean);
-    method public void removeFragmentOnAttachListener(androidx.fragment.app.FragmentOnAttachListener);
-    method public void removeOnBackStackChangedListener(androidx.fragment.app.FragmentManager.OnBackStackChangedListener);
-    method public void restoreBackStack(String);
-    method public void saveBackStack(String);
-    method public androidx.fragment.app.Fragment.SavedState? saveFragmentInstanceState(androidx.fragment.app.Fragment);
-    method public void setFragmentFactory(androidx.fragment.app.FragmentFactory);
-    method public final void setFragmentResult(String, android.os.Bundle);
-    method public final void setFragmentResultListener(String, androidx.lifecycle.LifecycleOwner, androidx.fragment.app.FragmentResultListener);
-    method public void setStrictModePolicy(androidx.fragment.app.strictmode.FragmentStrictMode.Policy?);
-    method public void unregisterFragmentLifecycleCallbacks(androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks);
-    field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
-  }
-
-  public static interface FragmentManager.BackStackEntry {
-    method @Deprecated public CharSequence? getBreadCrumbShortTitle();
-    method @Deprecated @StringRes public int getBreadCrumbShortTitleRes();
-    method @Deprecated public CharSequence? getBreadCrumbTitle();
-    method @Deprecated @StringRes public int getBreadCrumbTitleRes();
-    method public int getId();
-    method public String? getName();
-  }
-
-  public abstract static class FragmentManager.FragmentLifecycleCallbacks {
-    ctor public FragmentManager.FragmentLifecycleCallbacks();
-    method @Deprecated public void onFragmentActivityCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
-    method public void onFragmentAttached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.content.Context);
-    method public void onFragmentCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
-    method public void onFragmentDestroyed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentDetached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentPaused(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentPreAttached(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.content.Context);
-    method public void onFragmentPreCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle?);
-    method public void onFragmentResumed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentSaveInstanceState(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.os.Bundle);
-    method public void onFragmentStarted(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentStopped(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-    method public void onFragmentViewCreated(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment, android.view.View, android.os.Bundle?);
-    method public void onFragmentViewDestroyed(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-  }
-
-  public static interface FragmentManager.OnBackStackChangedListener {
-    method @MainThread public void onBackStackChanged();
-  }
-
-  @Deprecated public class FragmentManagerNonConfig {
-  }
-
-  public interface FragmentOnAttachListener {
-    method @MainThread public void onAttachFragment(androidx.fragment.app.FragmentManager, androidx.fragment.app.Fragment);
-  }
-
-  @Deprecated public abstract class FragmentPagerAdapter extends androidx.viewpager.widget.PagerAdapter {
-    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager);
-    ctor @Deprecated public FragmentPagerAdapter(androidx.fragment.app.FragmentManager, int);
-    method @Deprecated public abstract androidx.fragment.app.Fragment getItem(int);
-    method @Deprecated public long getItemId(int);
-    method @Deprecated public boolean isViewFromObject(android.view.View, Object);
-    field @Deprecated public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1; // 0x1
-    field @Deprecated public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0; // 0x0
-  }
-
-  public interface FragmentResultListener {
-    method public void onFragmentResult(String, android.os.Bundle);
-  }
-
-  public interface FragmentResultOwner {
-    method public void clearFragmentResult(String);
-    method public void clearFragmentResultListener(String);
-    method public void setFragmentResult(String, android.os.Bundle);
-    method public void setFragmentResultListener(String, androidx.lifecycle.LifecycleOwner, androidx.fragment.app.FragmentResultListener);
-  }
-
-  @Deprecated public abstract class FragmentStatePagerAdapter extends androidx.viewpager.widget.PagerAdapter {
-    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager);
-    ctor @Deprecated public FragmentStatePagerAdapter(androidx.fragment.app.FragmentManager, int);
-    method @Deprecated public abstract androidx.fragment.app.Fragment getItem(int);
-    method @Deprecated public boolean isViewFromObject(android.view.View, Object);
-    field @Deprecated public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1; // 0x1
-    field @Deprecated public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0; // 0x0
-  }
-
-  @Deprecated public class FragmentTabHost extends android.widget.TabHost implements android.widget.TabHost.OnTabChangeListener {
-    ctor @Deprecated public FragmentTabHost(android.content.Context);
-    ctor @Deprecated public FragmentTabHost(android.content.Context, android.util.AttributeSet?);
-    method @Deprecated public void addTab(android.widget.TabHost.TabSpec, Class<?>, android.os.Bundle?);
-    method @Deprecated public void onTabChanged(String?);
-    method @Deprecated public void setup(android.content.Context, androidx.fragment.app.FragmentManager);
-    method @Deprecated public void setup(android.content.Context, androidx.fragment.app.FragmentManager, int);
-  }
-
-  public abstract class FragmentTransaction {
-    ctor @Deprecated public FragmentTransaction();
-    method public final androidx.fragment.app.FragmentTransaction add(Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
-    method public androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.Fragment, String?);
-    method public final androidx.fragment.app.FragmentTransaction add(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?);
-    method public androidx.fragment.app.FragmentTransaction add(@IdRes int, androidx.fragment.app.Fragment);
-    method public final androidx.fragment.app.FragmentTransaction add(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
-    method public androidx.fragment.app.FragmentTransaction add(@IdRes int, androidx.fragment.app.Fragment, String?);
-    method public androidx.fragment.app.FragmentTransaction addSharedElement(android.view.View, String);
-    method public androidx.fragment.app.FragmentTransaction addToBackStack(String?);
-    method public androidx.fragment.app.FragmentTransaction attach(androidx.fragment.app.Fragment);
-    method public abstract int commit();
-    method public abstract int commitAllowingStateLoss();
-    method public abstract void commitNow();
-    method public abstract void commitNowAllowingStateLoss();
-    method public androidx.fragment.app.FragmentTransaction detach(androidx.fragment.app.Fragment);
-    method public androidx.fragment.app.FragmentTransaction disallowAddToBackStack();
-    method public androidx.fragment.app.FragmentTransaction hide(androidx.fragment.app.Fragment);
-    method public boolean isAddToBackStackAllowed();
-    method public boolean isEmpty();
-    method public androidx.fragment.app.FragmentTransaction remove(androidx.fragment.app.Fragment);
-    method public final androidx.fragment.app.FragmentTransaction replace(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?);
-    method public androidx.fragment.app.FragmentTransaction replace(@IdRes int, androidx.fragment.app.Fragment);
-    method public final androidx.fragment.app.FragmentTransaction replace(@IdRes int, Class<? extends androidx.fragment.app.Fragment>, android.os.Bundle?, String?);
-    method public androidx.fragment.app.FragmentTransaction replace(@IdRes int, androidx.fragment.app.Fragment, String?);
-    method public androidx.fragment.app.FragmentTransaction runOnCommit(Runnable);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setAllowOptimization(boolean);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbShortTitle(@StringRes int);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbShortTitle(CharSequence?);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbTitle(@StringRes int);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setBreadCrumbTitle(CharSequence?);
-    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int);
-    method public androidx.fragment.app.FragmentTransaction setCustomAnimations(@AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int, @AnimRes @AnimatorRes int);
-    method public androidx.fragment.app.FragmentTransaction setMaxLifecycle(androidx.fragment.app.Fragment, androidx.lifecycle.Lifecycle.State);
-    method public androidx.fragment.app.FragmentTransaction setPrimaryNavigationFragment(androidx.fragment.app.Fragment?);
-    method public androidx.fragment.app.FragmentTransaction setReorderingAllowed(boolean);
-    method public androidx.fragment.app.FragmentTransaction setTransition(int);
-    method @Deprecated public androidx.fragment.app.FragmentTransaction setTransitionStyle(@StyleRes int);
-    method public androidx.fragment.app.FragmentTransaction show(androidx.fragment.app.Fragment);
-    field public static final int TRANSIT_ENTER_MASK = 4096; // 0x1000
-    field public static final int TRANSIT_EXIT_MASK = 8192; // 0x2000
-    field public static final int TRANSIT_FRAGMENT_CLOSE = 8194; // 0x2002
-    field public static final int TRANSIT_FRAGMENT_FADE = 4099; // 0x1003
-    field public static final int TRANSIT_FRAGMENT_MATCH_ACTIVITY_CLOSE = 8197; // 0x2005
-    field public static final int TRANSIT_FRAGMENT_MATCH_ACTIVITY_OPEN = 4100; // 0x1004
-    field public static final int TRANSIT_FRAGMENT_OPEN = 4097; // 0x1001
-    field public static final int TRANSIT_NONE = 0; // 0x0
-    field public static final int TRANSIT_UNSET = -1; // 0xffffffff
-  }
-
-  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class FragmentTransitionImpl {
-    ctor public FragmentTransitionImpl();
-    method public abstract void addTarget(Object!, android.view.View!);
-    method public abstract void addTargets(Object!, java.util.ArrayList<android.view.View!>!);
-    method public abstract void beginDelayedTransition(android.view.ViewGroup!, Object!);
-    method protected static void bfsAddViewChildren(java.util.List<android.view.View!>!, android.view.View!);
-    method public abstract boolean canHandle(Object!);
-    method public abstract Object! cloneTransition(Object!);
-    method protected void getBoundsOnScreen(android.view.View!, android.graphics.Rect!);
-    method protected static boolean isNullOrEmpty(java.util.List!);
-    method public abstract Object! mergeTransitionsInSequence(Object!, Object!, Object!);
-    method public abstract Object! mergeTransitionsTogether(Object!, Object!, Object!);
-    method public abstract void removeTarget(Object!, android.view.View!);
-    method public abstract void replaceTargets(Object!, java.util.ArrayList<android.view.View!>!, java.util.ArrayList<android.view.View!>!);
-    method public abstract void scheduleHideFragmentView(Object!, android.view.View!, java.util.ArrayList<android.view.View!>!);
-    method public abstract void scheduleRemoveTargets(Object!, Object!, java.util.ArrayList<android.view.View!>!, Object!, java.util.ArrayList<android.view.View!>!, Object!, java.util.ArrayList<android.view.View!>!);
-    method public abstract void setEpicenter(Object!, android.view.View!);
-    method public abstract void setEpicenter(Object!, android.graphics.Rect!);
-    method public void setListenerForTransitionEnd(androidx.fragment.app.Fragment, Object, androidx.core.os.CancellationSignal, Runnable);
-    method public abstract void setSharedElementTargets(Object!, android.view.View!, java.util.ArrayList<android.view.View!>!);
-    method public abstract void swapSharedElementTargets(Object!, java.util.ArrayList<android.view.View!>!, java.util.ArrayList<android.view.View!>!);
-    method public abstract Object! wrapTransitionInSet(Object!);
-  }
-
-  public class ListFragment extends androidx.fragment.app.Fragment {
-    ctor public ListFragment();
-    method public android.widget.ListAdapter? getListAdapter();
-    method public android.widget.ListView getListView();
-    method public long getSelectedItemId();
-    method public int getSelectedItemPosition();
-    method public void onListItemClick(android.widget.ListView, android.view.View, int, long);
-    method public final android.widget.ListAdapter requireListAdapter();
-    method public void setEmptyText(CharSequence?);
-    method public void setListAdapter(android.widget.ListAdapter?);
-    method public void setListShown(boolean);
-    method public void setListShownNoAnimation(boolean);
-    method public void setSelection(int);
-  }
-
-}
-
-package androidx.fragment.app.strictmode {
-
-  public final class FragmentReuseViolation extends androidx.fragment.app.strictmode.Violation {
-    method public String getPreviousFragmentId();
-    property public final String previousFragmentId;
-  }
-
-  public final class FragmentStrictMode {
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy getDefaultPolicy();
-    method @VisibleForTesting public void onPolicyViolation(androidx.fragment.app.strictmode.Violation violation);
-    method public void setDefaultPolicy(androidx.fragment.app.strictmode.FragmentStrictMode.Policy);
-    property public final androidx.fragment.app.strictmode.FragmentStrictMode.Policy defaultPolicy;
-    field public static final androidx.fragment.app.strictmode.FragmentStrictMode INSTANCE;
-  }
-
-  public static fun interface FragmentStrictMode.OnViolationListener {
-    method public void onViolation(androidx.fragment.app.strictmode.Violation violation);
-  }
-
-  public static final class FragmentStrictMode.Policy {
-    field public static final androidx.fragment.app.strictmode.FragmentStrictMode.Policy LAX;
-  }
-
-  public static final class FragmentStrictMode.Policy.Builder {
-    ctor public FragmentStrictMode.Policy.Builder();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder allowViolation(Class<? extends androidx.fragment.app.Fragment> fragmentClass, Class<? extends androidx.fragment.app.strictmode.Violation> violationClass);
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder allowViolation(String fragmentClass, Class<? extends androidx.fragment.app.strictmode.Violation> violationClass);
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy build();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectFragmentReuse();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectFragmentTagUsage();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectRetainInstanceUsage();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectSetUserVisibleHint();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectTargetFragmentUsage();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectWrongFragmentContainer();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyDeath();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyListener(androidx.fragment.app.strictmode.FragmentStrictMode.OnViolationListener listener);
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyLog();
-  }
-
-  public final class FragmentTagUsageViolation extends androidx.fragment.app.strictmode.Violation {
-    method public android.view.ViewGroup? getParentContainer();
-    property public final android.view.ViewGroup? parentContainer;
-  }
-
-  public final class GetRetainInstanceUsageViolation extends androidx.fragment.app.strictmode.RetainInstanceUsageViolation {
-  }
-
-  public final class GetTargetFragmentRequestCodeUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
-  }
-
-  public final class GetTargetFragmentUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
-  }
-
-  public abstract class RetainInstanceUsageViolation extends androidx.fragment.app.strictmode.Violation {
-  }
-
-  public final class SetRetainInstanceUsageViolation extends androidx.fragment.app.strictmode.RetainInstanceUsageViolation {
-  }
-
-  public final class SetTargetFragmentUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
-    method public int getRequestCode();
-    method public androidx.fragment.app.Fragment getTargetFragment();
-    property public final int requestCode;
-    property public final androidx.fragment.app.Fragment targetFragment;
-  }
-
-  public final class SetUserVisibleHintViolation extends androidx.fragment.app.strictmode.Violation {
-    method public boolean isVisibleToUser();
-    property public final boolean isVisibleToUser;
-  }
-
-  public abstract class TargetFragmentUsageViolation extends androidx.fragment.app.strictmode.Violation {
-  }
-
-  public abstract class Violation extends java.lang.RuntimeException {
-    method public final androidx.fragment.app.Fragment getFragment();
-    property public final androidx.fragment.app.Fragment fragment;
-  }
-
-  public final class WrongFragmentContainerViolation extends androidx.fragment.app.strictmode.Violation {
-    method public android.view.ViewGroup getContainer();
-    property public final android.view.ViewGroup container;
-  }
-
-}
-
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/action/ActionTrampoline.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/action/ActionTrampoline.kt
index 486e1fa..0905d7e 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/action/ActionTrampoline.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/action/ActionTrampoline.kt
@@ -82,6 +82,7 @@
  *
  * @see applyTrampolineIntent
  */
+@Suppress("DEPRECATION")
 internal fun Activity.launchTrampolineAction(intent: Intent) {
     val actionIntent = requireNotNull(intent.getParcelableExtra<Intent>(ActionIntentKey)) {
         "List adapter activity trampoline invoked without specifying target intent."
diff --git a/gradle.properties b/gradle.properties
index 22d731a..52f8735 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -23,8 +23,11 @@
 android.forceJacocoOutOfProcess=true
 android.experimental.lint.missingBaselineIsEmptyBaseline=true
 
-# Generate versioned API files
-androidx.writeVersionedApiFiles=true
+# Don't generate versioned API files
+androidx.writeVersionedApiFiles=false
+
+# Don't warn about needing to update AGP
+android.suppressUnsupportedCompileSdk=Tiramisu
 
 # Disable features we do not use
 android.defaults.buildfeatures.aidl=false
diff --git a/graphics/OWNERS b/graphics/OWNERS
new file mode 100644
index 0000000..db046a2
--- /dev/null
+++ b/graphics/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 1137062
[email protected]
[email protected]
[email protected]
[email protected]
\ No newline at end of file
diff --git a/graphics/graphics-core/api/current.txt b/graphics/graphics-core/api/current.txt
new file mode 100644
index 0000000..7582268
--- /dev/null
+++ b/graphics/graphics-core/api/current.txt
@@ -0,0 +1,255 @@
+// Signature format: 4.0
+package androidx.graphics.opengl {
+
+  public final class GLRenderer {
+    ctor public GLRenderer(optional kotlin.jvm.functions.Function0<? extends androidx.graphics.opengl.egl.EglSpec> eglSpecFactory, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.egl.EglManager,? extends android.opengl.EGLConfig> eglConfigFactory);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.Surface surface, int width, int height, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.SurfaceView surfaceView, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.TextureView textureView, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public void detach(androidx.graphics.opengl.GLRenderer.RenderTarget target, boolean cancelPending, optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onDetachComplete);
+    method public void detach(androidx.graphics.opengl.GLRenderer.RenderTarget target, boolean cancelPending);
+    method public boolean isRunning();
+    method public void registerEglContextCallback(androidx.graphics.opengl.GLRenderer.EglContextCallback callback);
+    method public void requestRender(androidx.graphics.opengl.GLRenderer.RenderTarget target, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onRenderComplete);
+    method public void requestRender(androidx.graphics.opengl.GLRenderer.RenderTarget target);
+    method public void resize(androidx.graphics.opengl.GLRenderer.RenderTarget target, int width, int height, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onResizeComplete);
+    method public void resize(androidx.graphics.opengl.GLRenderer.RenderTarget target, int width, int height);
+    method public void start(optional String name);
+    method public void start();
+    method public void stop(boolean cancelPending, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer,kotlin.Unit>? onStop);
+    method public void stop(boolean cancelPending);
+    method public void unregisterEglContextCallback(androidx.graphics.opengl.GLRenderer.EglContextCallback callback);
+    field public static final androidx.graphics.opengl.GLRenderer.Companion Companion;
+  }
+
+  public static final class GLRenderer.Companion {
+  }
+
+  public static interface GLRenderer.EglContextCallback {
+    method @WorkerThread public void onEglContextCreated(androidx.graphics.opengl.egl.EglManager eglManager);
+    method @WorkerThread public void onEglContextDestroyed(androidx.graphics.opengl.egl.EglManager eglManager);
+  }
+
+  public static interface GLRenderer.RenderCallback {
+    method @WorkerThread public void onDrawFrame(androidx.graphics.opengl.egl.EglManager eglManager);
+    method @WorkerThread public default android.opengl.EGLSurface onSurfaceCreated(androidx.graphics.opengl.egl.EglSpec spec, android.opengl.EGLConfig config, android.view.Surface surface, int width, int height);
+  }
+
+  public static final class GLRenderer.RenderTarget {
+    method public void detach(boolean cancelPending, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onDetachComplete);
+    method public void detach(boolean cancelPending);
+    method public boolean isAttached();
+    method public void requestRender(optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onRenderComplete);
+    method public void requestRender();
+    method public void resize(int width, int height, optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onResizeComplete);
+    method public void resize(int width, int height);
+  }
+
+}
+
+package androidx.graphics.opengl.egl {
+
+  public interface EGLHandle {
+    method public long getNativeHandle();
+    property public abstract long nativeHandle;
+  }
+
+  public final class EGLImageKHR implements androidx.graphics.opengl.egl.EGLHandle {
+    ctor public EGLImageKHR(long nativeHandle);
+    method public long getNativeHandle();
+    property public long nativeHandle;
+  }
+
+  public final class EGLSyncKHR implements androidx.graphics.opengl.egl.EGLHandle {
+    ctor public EGLSyncKHR(long nativeHandle);
+    method public long getNativeHandle();
+    property public long nativeHandle;
+  }
+
+  public final class EGLUtils {
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static androidx.graphics.opengl.egl.EGLImageKHR? eglCreateImageFromHardwareBuffer(android.opengl.EGLDisplay eglDisplay, android.hardware.HardwareBuffer hardwareBuffer);
+    method public static androidx.graphics.opengl.egl.EGLSyncKHR? eglCreateSyncKHR(android.opengl.EGLDisplay eglDisplay, int type, int[]? attributes);
+    method public static boolean eglDestroyImageKHR(android.opengl.EGLDisplay eglDisplay, androidx.graphics.opengl.egl.EGLImageKHR image);
+    method public static boolean eglDestroySyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.graphics.opengl.egl.EGLSyncKHR eglSync);
+    method public static void glEGLImageTargetTexture2DOES(int target, androidx.graphics.opengl.egl.EGLImageKHR image);
+    field public static final androidx.graphics.opengl.egl.EGLUtils.Companion Companion;
+    field public static final int EGL_SYNC_NATIVE_FENCE_ANDROID = 12612; // 0x3144
+  }
+
+  public static final class EGLUtils.Companion {
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public androidx.graphics.opengl.egl.EGLImageKHR? eglCreateImageFromHardwareBuffer(android.opengl.EGLDisplay eglDisplay, android.hardware.HardwareBuffer hardwareBuffer);
+    method public androidx.graphics.opengl.egl.EGLSyncKHR? eglCreateSyncKHR(android.opengl.EGLDisplay eglDisplay, int type, int[]? attributes);
+    method public boolean eglDestroyImageKHR(android.opengl.EGLDisplay eglDisplay, androidx.graphics.opengl.egl.EGLImageKHR image);
+    method public boolean eglDestroySyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.graphics.opengl.egl.EGLSyncKHR eglSync);
+    method public void glEGLImageTargetTexture2DOES(int target, androidx.graphics.opengl.egl.EGLImageKHR image);
+  }
+
+  public final inline class EglConfigAttributes {
+    ctor public EglConfigAttributes();
+  }
+
+  public static final class EglConfigAttributes.Builder {
+    method public void include(int[] attributes);
+    method public infix void to(int, int that);
+  }
+
+  public final class EglConfigAttributesKt {
+    method public static inline int[] EglConfigAttributes(kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.egl.EglConfigAttributes.Builder,kotlin.Unit> block);
+    method public static int[] getEglConfigAttributes1010102();
+    method public static int[] getEglConfigAttributes8888();
+    method public static int[] getEglConfigAttributesF16();
+    property public static final int[] EglConfigAttributes1010102;
+    property public static final int[] EglConfigAttributes8888;
+    property public static final int[] EglConfigAttributesF16;
+    field public static final int EglColorComponentTypeExt = 13113; // 0x3339
+    field public static final int EglColorComponentTypeFixedExt = 13114; // 0x333a
+    field public static final int EglColorComponentTypeFloatExt = 13115; // 0x333b
+  }
+
+  public final class EglException extends java.lang.RuntimeException {
+    ctor public EglException(int error, optional String msg);
+    method public int getError();
+    method public String getMsg();
+    property public final int error;
+    property public String message;
+    property public final String msg;
+  }
+
+  public final inline class EglExtensions {
+    ctor public EglExtensions();
+  }
+
+  public static final class EglExtensions.Companion {
+    method public java.util.Set<? extends java.lang.String> from(String queryString);
+  }
+
+  public final class EglExtensionsKt {
+    field public static final String EglAndroidImageNativeBuffer = "EGL_ANDROID_image_native_buffer";
+    field public static final String EglAndroidNativeFenceSync = "EGL_ANDROID_native_fence_sync";
+    field public static final String EglExtBufferAge = "EGL_EXT_buffer_age";
+    field public static final String EglExtColorSpaceDisplayP3Passthrough = "EGL_EXT_gl_colorspace_display_p3_passthrough";
+    field public static final String EglExtGlColorSpaceBt2020Pq = "EGL_EXT_gl_colorspace_bt2020_pq";
+    field public static final String EglExtGlColorSpaceScRgb = "EGL_EXT_gl_colorspace_scrgb";
+    field public static final String EglExtPixelFormatFloat = "EGL_EXT_pixel_format_float";
+    field public static final String EglImgContextPriority = "EGL_IMG_context_priority";
+    field public static final String EglKhrFenceSync = "EGL_KHR_fence_sync";
+    field public static final String EglKhrGlColorSpace = "EGL_KHR_gl_colorspace";
+    field public static final String EglKhrImage = "EGL_KHR_image";
+    field public static final String EglKhrImageBase = "EGL_KHR_image_base";
+    field public static final String EglKhrNoConfigContext = "EGL_KHR_no_config_context";
+    field public static final String EglKhrPartialUpdate = "EGL_KHR_partial_update";
+    field public static final String EglKhrSurfacelessContext = "EGL_KHR_surfaceless_context";
+    field public static final String EglKhrSwapBuffersWithDamage = "EGL_KHR_swap_buffers_with_damage";
+    field public static final String EglKhrWaitSync = "EGL_KHR_wait_sync";
+  }
+
+  public final class EglManager {
+    ctor public EglManager(optional androidx.graphics.opengl.egl.EglSpec eglSpec);
+    method public android.opengl.EGLContext createContext(android.opengl.EGLConfig config);
+    method public android.opengl.EGLSurface getCurrentDrawSurface();
+    method public android.opengl.EGLSurface getCurrentReadSurface();
+    method public android.opengl.EGLSurface getDefaultSurface();
+    method public android.opengl.EGLConfig? getEglConfig();
+    method public android.opengl.EGLContext? getEglContext();
+    method public androidx.graphics.opengl.egl.EglSpec getEglSpec();
+    method public androidx.graphics.opengl.egl.EglVersion getEglVersion();
+    method public void initialize();
+    method public boolean isExtensionSupported(String extensionName);
+    method public android.opengl.EGLConfig? loadConfig(int[] configAttributes);
+    method public boolean makeCurrent(android.opengl.EGLSurface drawSurface, optional android.opengl.EGLSurface readSurface);
+    method public boolean makeCurrent(android.opengl.EGLSurface drawSurface);
+    method public void release();
+    method public void swapAndFlushBuffers();
+    property public final android.opengl.EGLSurface currentDrawSurface;
+    property public final android.opengl.EGLSurface currentReadSurface;
+    property public final android.opengl.EGLSurface defaultSurface;
+    property public final android.opengl.EGLConfig? eglConfig;
+    property public final android.opengl.EGLContext? eglContext;
+    property public final androidx.graphics.opengl.egl.EglSpec eglSpec;
+    property public final androidx.graphics.opengl.egl.EglVersion eglVersion;
+    field public static final androidx.graphics.opengl.egl.EglManager.Companion Companion;
+  }
+
+  public static final class EglManager.Companion {
+  }
+
+  public interface EglSpec {
+    method public android.opengl.EGLContext eglCreateContext(android.opengl.EGLConfig config);
+    method public android.opengl.EGLSurface eglCreatePBufferSurface(android.opengl.EGLConfig config, int[]? configAttributes);
+    method public android.opengl.EGLSurface eglCreateWindowSurface(android.opengl.EGLConfig config, android.view.Surface surface, int[]? configAttributes);
+    method public void eglDestroyContext(android.opengl.EGLContext eglContext);
+    method public boolean eglDestroySurface(android.opengl.EGLSurface surface);
+    method public android.opengl.EGLSurface eglGetCurrentDrawSurface();
+    method public android.opengl.EGLSurface eglGetCurrentReadSurface();
+    method public int eglGetError();
+    method public androidx.graphics.opengl.egl.EglVersion eglInitialize();
+    method public boolean eglMakeCurrent(android.opengl.EGLContext context, android.opengl.EGLSurface drawSurface, android.opengl.EGLSurface readSurface);
+    method public String eglQueryString(int nameId);
+    method public boolean eglQuerySurface(android.opengl.EGLSurface surface, int attribute, int[] result, int offset);
+    method public boolean eglSwapBuffers(android.opengl.EGLSurface surface);
+    method public default String getErrorMessage();
+    method public default static String getStatusString(int error);
+    method public android.opengl.EGLConfig? loadConfig(int[] configAttributes);
+    field public static final androidx.graphics.opengl.egl.EglSpec.Companion Companion;
+    field public static final androidx.graphics.opengl.egl.EglSpec Egl14;
+  }
+
+  public static final class EglSpec.Companion {
+    method public String getStatusString(int error);
+  }
+
+  public final class EglVersion {
+    ctor public EglVersion(int major, int minor);
+    method public int component1();
+    method public int component2();
+    method public androidx.graphics.opengl.egl.EglVersion copy(int major, int minor);
+    method public int getMajor();
+    method public int getMinor();
+    property public final int major;
+    property public final int minor;
+    field public static final androidx.graphics.opengl.egl.EglVersion.Companion Companion;
+    field public static final androidx.graphics.opengl.egl.EglVersion Unknown;
+    field public static final androidx.graphics.opengl.egl.EglVersion V14;
+    field public static final androidx.graphics.opengl.egl.EglVersion V15;
+  }
+
+  public static final class EglVersion.Companion {
+  }
+
+}
+
+package androidx.graphics.surface {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class SurfaceControlCompat {
+    method protected void finalize();
+    field public static final androidx.graphics.surface.SurfaceControlCompat.Companion Companion;
+  }
+
+  public static final class SurfaceControlCompat.Builder {
+    ctor public SurfaceControlCompat.Builder(android.view.Surface surface);
+    ctor public SurfaceControlCompat.Builder(androidx.graphics.surface.SurfaceControlCompat surfaceControl);
+    method public androidx.graphics.surface.SurfaceControlCompat build();
+    method public androidx.graphics.surface.SurfaceControlCompat.Builder setDebugName(String debugName);
+  }
+
+  public static final class SurfaceControlCompat.Companion {
+  }
+
+  public static class SurfaceControlCompat.Transaction {
+    ctor public SurfaceControlCompat.Transaction();
+    method public final void addTransactionCompletedListener(androidx.graphics.surface.SurfaceControlCompat.TransactionCompletedListener listener);
+    method public final void commit();
+    method public final void delete();
+    method public final void finalize();
+    field public static final androidx.graphics.surface.SurfaceControlCompat.Transaction.Companion Companion;
+  }
+
+  public static final class SurfaceControlCompat.Transaction.Companion {
+  }
+
+  public static interface SurfaceControlCompat.TransactionCompletedListener {
+    method public void onComplete(long latchTime, long presentTime);
+  }
+
+}
+
diff --git a/graphics/graphics-core/api/public_plus_experimental_current.txt b/graphics/graphics-core/api/public_plus_experimental_current.txt
new file mode 100644
index 0000000..7582268
--- /dev/null
+++ b/graphics/graphics-core/api/public_plus_experimental_current.txt
@@ -0,0 +1,255 @@
+// Signature format: 4.0
+package androidx.graphics.opengl {
+
+  public final class GLRenderer {
+    ctor public GLRenderer(optional kotlin.jvm.functions.Function0<? extends androidx.graphics.opengl.egl.EglSpec> eglSpecFactory, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.egl.EglManager,? extends android.opengl.EGLConfig> eglConfigFactory);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.Surface surface, int width, int height, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.SurfaceView surfaceView, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.TextureView textureView, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public void detach(androidx.graphics.opengl.GLRenderer.RenderTarget target, boolean cancelPending, optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onDetachComplete);
+    method public void detach(androidx.graphics.opengl.GLRenderer.RenderTarget target, boolean cancelPending);
+    method public boolean isRunning();
+    method public void registerEglContextCallback(androidx.graphics.opengl.GLRenderer.EglContextCallback callback);
+    method public void requestRender(androidx.graphics.opengl.GLRenderer.RenderTarget target, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onRenderComplete);
+    method public void requestRender(androidx.graphics.opengl.GLRenderer.RenderTarget target);
+    method public void resize(androidx.graphics.opengl.GLRenderer.RenderTarget target, int width, int height, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onResizeComplete);
+    method public void resize(androidx.graphics.opengl.GLRenderer.RenderTarget target, int width, int height);
+    method public void start(optional String name);
+    method public void start();
+    method public void stop(boolean cancelPending, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer,kotlin.Unit>? onStop);
+    method public void stop(boolean cancelPending);
+    method public void unregisterEglContextCallback(androidx.graphics.opengl.GLRenderer.EglContextCallback callback);
+    field public static final androidx.graphics.opengl.GLRenderer.Companion Companion;
+  }
+
+  public static final class GLRenderer.Companion {
+  }
+
+  public static interface GLRenderer.EglContextCallback {
+    method @WorkerThread public void onEglContextCreated(androidx.graphics.opengl.egl.EglManager eglManager);
+    method @WorkerThread public void onEglContextDestroyed(androidx.graphics.opengl.egl.EglManager eglManager);
+  }
+
+  public static interface GLRenderer.RenderCallback {
+    method @WorkerThread public void onDrawFrame(androidx.graphics.opengl.egl.EglManager eglManager);
+    method @WorkerThread public default android.opengl.EGLSurface onSurfaceCreated(androidx.graphics.opengl.egl.EglSpec spec, android.opengl.EGLConfig config, android.view.Surface surface, int width, int height);
+  }
+
+  public static final class GLRenderer.RenderTarget {
+    method public void detach(boolean cancelPending, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onDetachComplete);
+    method public void detach(boolean cancelPending);
+    method public boolean isAttached();
+    method public void requestRender(optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onRenderComplete);
+    method public void requestRender();
+    method public void resize(int width, int height, optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onResizeComplete);
+    method public void resize(int width, int height);
+  }
+
+}
+
+package androidx.graphics.opengl.egl {
+
+  public interface EGLHandle {
+    method public long getNativeHandle();
+    property public abstract long nativeHandle;
+  }
+
+  public final class EGLImageKHR implements androidx.graphics.opengl.egl.EGLHandle {
+    ctor public EGLImageKHR(long nativeHandle);
+    method public long getNativeHandle();
+    property public long nativeHandle;
+  }
+
+  public final class EGLSyncKHR implements androidx.graphics.opengl.egl.EGLHandle {
+    ctor public EGLSyncKHR(long nativeHandle);
+    method public long getNativeHandle();
+    property public long nativeHandle;
+  }
+
+  public final class EGLUtils {
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static androidx.graphics.opengl.egl.EGLImageKHR? eglCreateImageFromHardwareBuffer(android.opengl.EGLDisplay eglDisplay, android.hardware.HardwareBuffer hardwareBuffer);
+    method public static androidx.graphics.opengl.egl.EGLSyncKHR? eglCreateSyncKHR(android.opengl.EGLDisplay eglDisplay, int type, int[]? attributes);
+    method public static boolean eglDestroyImageKHR(android.opengl.EGLDisplay eglDisplay, androidx.graphics.opengl.egl.EGLImageKHR image);
+    method public static boolean eglDestroySyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.graphics.opengl.egl.EGLSyncKHR eglSync);
+    method public static void glEGLImageTargetTexture2DOES(int target, androidx.graphics.opengl.egl.EGLImageKHR image);
+    field public static final androidx.graphics.opengl.egl.EGLUtils.Companion Companion;
+    field public static final int EGL_SYNC_NATIVE_FENCE_ANDROID = 12612; // 0x3144
+  }
+
+  public static final class EGLUtils.Companion {
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public androidx.graphics.opengl.egl.EGLImageKHR? eglCreateImageFromHardwareBuffer(android.opengl.EGLDisplay eglDisplay, android.hardware.HardwareBuffer hardwareBuffer);
+    method public androidx.graphics.opengl.egl.EGLSyncKHR? eglCreateSyncKHR(android.opengl.EGLDisplay eglDisplay, int type, int[]? attributes);
+    method public boolean eglDestroyImageKHR(android.opengl.EGLDisplay eglDisplay, androidx.graphics.opengl.egl.EGLImageKHR image);
+    method public boolean eglDestroySyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.graphics.opengl.egl.EGLSyncKHR eglSync);
+    method public void glEGLImageTargetTexture2DOES(int target, androidx.graphics.opengl.egl.EGLImageKHR image);
+  }
+
+  public final inline class EglConfigAttributes {
+    ctor public EglConfigAttributes();
+  }
+
+  public static final class EglConfigAttributes.Builder {
+    method public void include(int[] attributes);
+    method public infix void to(int, int that);
+  }
+
+  public final class EglConfigAttributesKt {
+    method public static inline int[] EglConfigAttributes(kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.egl.EglConfigAttributes.Builder,kotlin.Unit> block);
+    method public static int[] getEglConfigAttributes1010102();
+    method public static int[] getEglConfigAttributes8888();
+    method public static int[] getEglConfigAttributesF16();
+    property public static final int[] EglConfigAttributes1010102;
+    property public static final int[] EglConfigAttributes8888;
+    property public static final int[] EglConfigAttributesF16;
+    field public static final int EglColorComponentTypeExt = 13113; // 0x3339
+    field public static final int EglColorComponentTypeFixedExt = 13114; // 0x333a
+    field public static final int EglColorComponentTypeFloatExt = 13115; // 0x333b
+  }
+
+  public final class EglException extends java.lang.RuntimeException {
+    ctor public EglException(int error, optional String msg);
+    method public int getError();
+    method public String getMsg();
+    property public final int error;
+    property public String message;
+    property public final String msg;
+  }
+
+  public final inline class EglExtensions {
+    ctor public EglExtensions();
+  }
+
+  public static final class EglExtensions.Companion {
+    method public java.util.Set<? extends java.lang.String> from(String queryString);
+  }
+
+  public final class EglExtensionsKt {
+    field public static final String EglAndroidImageNativeBuffer = "EGL_ANDROID_image_native_buffer";
+    field public static final String EglAndroidNativeFenceSync = "EGL_ANDROID_native_fence_sync";
+    field public static final String EglExtBufferAge = "EGL_EXT_buffer_age";
+    field public static final String EglExtColorSpaceDisplayP3Passthrough = "EGL_EXT_gl_colorspace_display_p3_passthrough";
+    field public static final String EglExtGlColorSpaceBt2020Pq = "EGL_EXT_gl_colorspace_bt2020_pq";
+    field public static final String EglExtGlColorSpaceScRgb = "EGL_EXT_gl_colorspace_scrgb";
+    field public static final String EglExtPixelFormatFloat = "EGL_EXT_pixel_format_float";
+    field public static final String EglImgContextPriority = "EGL_IMG_context_priority";
+    field public static final String EglKhrFenceSync = "EGL_KHR_fence_sync";
+    field public static final String EglKhrGlColorSpace = "EGL_KHR_gl_colorspace";
+    field public static final String EglKhrImage = "EGL_KHR_image";
+    field public static final String EglKhrImageBase = "EGL_KHR_image_base";
+    field public static final String EglKhrNoConfigContext = "EGL_KHR_no_config_context";
+    field public static final String EglKhrPartialUpdate = "EGL_KHR_partial_update";
+    field public static final String EglKhrSurfacelessContext = "EGL_KHR_surfaceless_context";
+    field public static final String EglKhrSwapBuffersWithDamage = "EGL_KHR_swap_buffers_with_damage";
+    field public static final String EglKhrWaitSync = "EGL_KHR_wait_sync";
+  }
+
+  public final class EglManager {
+    ctor public EglManager(optional androidx.graphics.opengl.egl.EglSpec eglSpec);
+    method public android.opengl.EGLContext createContext(android.opengl.EGLConfig config);
+    method public android.opengl.EGLSurface getCurrentDrawSurface();
+    method public android.opengl.EGLSurface getCurrentReadSurface();
+    method public android.opengl.EGLSurface getDefaultSurface();
+    method public android.opengl.EGLConfig? getEglConfig();
+    method public android.opengl.EGLContext? getEglContext();
+    method public androidx.graphics.opengl.egl.EglSpec getEglSpec();
+    method public androidx.graphics.opengl.egl.EglVersion getEglVersion();
+    method public void initialize();
+    method public boolean isExtensionSupported(String extensionName);
+    method public android.opengl.EGLConfig? loadConfig(int[] configAttributes);
+    method public boolean makeCurrent(android.opengl.EGLSurface drawSurface, optional android.opengl.EGLSurface readSurface);
+    method public boolean makeCurrent(android.opengl.EGLSurface drawSurface);
+    method public void release();
+    method public void swapAndFlushBuffers();
+    property public final android.opengl.EGLSurface currentDrawSurface;
+    property public final android.opengl.EGLSurface currentReadSurface;
+    property public final android.opengl.EGLSurface defaultSurface;
+    property public final android.opengl.EGLConfig? eglConfig;
+    property public final android.opengl.EGLContext? eglContext;
+    property public final androidx.graphics.opengl.egl.EglSpec eglSpec;
+    property public final androidx.graphics.opengl.egl.EglVersion eglVersion;
+    field public static final androidx.graphics.opengl.egl.EglManager.Companion Companion;
+  }
+
+  public static final class EglManager.Companion {
+  }
+
+  public interface EglSpec {
+    method public android.opengl.EGLContext eglCreateContext(android.opengl.EGLConfig config);
+    method public android.opengl.EGLSurface eglCreatePBufferSurface(android.opengl.EGLConfig config, int[]? configAttributes);
+    method public android.opengl.EGLSurface eglCreateWindowSurface(android.opengl.EGLConfig config, android.view.Surface surface, int[]? configAttributes);
+    method public void eglDestroyContext(android.opengl.EGLContext eglContext);
+    method public boolean eglDestroySurface(android.opengl.EGLSurface surface);
+    method public android.opengl.EGLSurface eglGetCurrentDrawSurface();
+    method public android.opengl.EGLSurface eglGetCurrentReadSurface();
+    method public int eglGetError();
+    method public androidx.graphics.opengl.egl.EglVersion eglInitialize();
+    method public boolean eglMakeCurrent(android.opengl.EGLContext context, android.opengl.EGLSurface drawSurface, android.opengl.EGLSurface readSurface);
+    method public String eglQueryString(int nameId);
+    method public boolean eglQuerySurface(android.opengl.EGLSurface surface, int attribute, int[] result, int offset);
+    method public boolean eglSwapBuffers(android.opengl.EGLSurface surface);
+    method public default String getErrorMessage();
+    method public default static String getStatusString(int error);
+    method public android.opengl.EGLConfig? loadConfig(int[] configAttributes);
+    field public static final androidx.graphics.opengl.egl.EglSpec.Companion Companion;
+    field public static final androidx.graphics.opengl.egl.EglSpec Egl14;
+  }
+
+  public static final class EglSpec.Companion {
+    method public String getStatusString(int error);
+  }
+
+  public final class EglVersion {
+    ctor public EglVersion(int major, int minor);
+    method public int component1();
+    method public int component2();
+    method public androidx.graphics.opengl.egl.EglVersion copy(int major, int minor);
+    method public int getMajor();
+    method public int getMinor();
+    property public final int major;
+    property public final int minor;
+    field public static final androidx.graphics.opengl.egl.EglVersion.Companion Companion;
+    field public static final androidx.graphics.opengl.egl.EglVersion Unknown;
+    field public static final androidx.graphics.opengl.egl.EglVersion V14;
+    field public static final androidx.graphics.opengl.egl.EglVersion V15;
+  }
+
+  public static final class EglVersion.Companion {
+  }
+
+}
+
+package androidx.graphics.surface {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class SurfaceControlCompat {
+    method protected void finalize();
+    field public static final androidx.graphics.surface.SurfaceControlCompat.Companion Companion;
+  }
+
+  public static final class SurfaceControlCompat.Builder {
+    ctor public SurfaceControlCompat.Builder(android.view.Surface surface);
+    ctor public SurfaceControlCompat.Builder(androidx.graphics.surface.SurfaceControlCompat surfaceControl);
+    method public androidx.graphics.surface.SurfaceControlCompat build();
+    method public androidx.graphics.surface.SurfaceControlCompat.Builder setDebugName(String debugName);
+  }
+
+  public static final class SurfaceControlCompat.Companion {
+  }
+
+  public static class SurfaceControlCompat.Transaction {
+    ctor public SurfaceControlCompat.Transaction();
+    method public final void addTransactionCompletedListener(androidx.graphics.surface.SurfaceControlCompat.TransactionCompletedListener listener);
+    method public final void commit();
+    method public final void delete();
+    method public final void finalize();
+    field public static final androidx.graphics.surface.SurfaceControlCompat.Transaction.Companion Companion;
+  }
+
+  public static final class SurfaceControlCompat.Transaction.Companion {
+  }
+
+  public static interface SurfaceControlCompat.TransactionCompletedListener {
+    method public void onComplete(long latchTime, long presentTime);
+  }
+
+}
+
diff --git a/core/core-ktx/api/res-1.8.0-beta01.txt b/graphics/graphics-core/api/res-current.txt
similarity index 100%
rename from core/core-ktx/api/res-1.8.0-beta01.txt
rename to graphics/graphics-core/api/res-current.txt
diff --git a/graphics/graphics-core/api/restricted_current.txt b/graphics/graphics-core/api/restricted_current.txt
new file mode 100644
index 0000000..54ab917
--- /dev/null
+++ b/graphics/graphics-core/api/restricted_current.txt
@@ -0,0 +1,257 @@
+// Signature format: 4.0
+package androidx.graphics.opengl {
+
+  public final class GLRenderer {
+    ctor public GLRenderer(optional kotlin.jvm.functions.Function0<? extends androidx.graphics.opengl.egl.EglSpec> eglSpecFactory, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.egl.EglManager,? extends android.opengl.EGLConfig> eglConfigFactory);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.Surface surface, int width, int height, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.SurfaceView surfaceView, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.TextureView textureView, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
+    method public void detach(androidx.graphics.opengl.GLRenderer.RenderTarget target, boolean cancelPending, optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onDetachComplete);
+    method public void detach(androidx.graphics.opengl.GLRenderer.RenderTarget target, boolean cancelPending);
+    method public boolean isRunning();
+    method public void registerEglContextCallback(androidx.graphics.opengl.GLRenderer.EglContextCallback callback);
+    method public void requestRender(androidx.graphics.opengl.GLRenderer.RenderTarget target, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onRenderComplete);
+    method public void requestRender(androidx.graphics.opengl.GLRenderer.RenderTarget target);
+    method public void resize(androidx.graphics.opengl.GLRenderer.RenderTarget target, int width, int height, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onResizeComplete);
+    method public void resize(androidx.graphics.opengl.GLRenderer.RenderTarget target, int width, int height);
+    method public void start(optional String name);
+    method public void start();
+    method public void stop(boolean cancelPending, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer,kotlin.Unit>? onStop);
+    method public void stop(boolean cancelPending);
+    method public void unregisterEglContextCallback(androidx.graphics.opengl.GLRenderer.EglContextCallback callback);
+    field public static final androidx.graphics.opengl.GLRenderer.Companion Companion;
+  }
+
+  public static final class GLRenderer.Companion {
+  }
+
+  public static interface GLRenderer.EglContextCallback {
+    method @WorkerThread public void onEglContextCreated(androidx.graphics.opengl.egl.EglManager eglManager);
+    method @WorkerThread public void onEglContextDestroyed(androidx.graphics.opengl.egl.EglManager eglManager);
+  }
+
+  public static interface GLRenderer.RenderCallback {
+    method @WorkerThread public void onDrawFrame(androidx.graphics.opengl.egl.EglManager eglManager);
+    method @WorkerThread public default android.opengl.EGLSurface onSurfaceCreated(androidx.graphics.opengl.egl.EglSpec spec, android.opengl.EGLConfig config, android.view.Surface surface, int width, int height);
+  }
+
+  public static final class GLRenderer.RenderTarget {
+    method public void detach(boolean cancelPending, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onDetachComplete);
+    method public void detach(boolean cancelPending);
+    method public boolean isAttached();
+    method public void requestRender(optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onRenderComplete);
+    method public void requestRender();
+    method public void resize(int width, int height, optional @WorkerThread kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.GLRenderer.RenderTarget,kotlin.Unit>? onResizeComplete);
+    method public void resize(int width, int height);
+  }
+
+}
+
+package androidx.graphics.opengl.egl {
+
+  public interface EGLHandle {
+    method public long getNativeHandle();
+    property public abstract long nativeHandle;
+  }
+
+  public final class EGLImageKHR implements androidx.graphics.opengl.egl.EGLHandle {
+    ctor public EGLImageKHR(long nativeHandle);
+    method public long getNativeHandle();
+    property public long nativeHandle;
+  }
+
+  public final class EGLSyncKHR implements androidx.graphics.opengl.egl.EGLHandle {
+    ctor public EGLSyncKHR(long nativeHandle);
+    method public long getNativeHandle();
+    property public long nativeHandle;
+  }
+
+  public final class EGLUtils {
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static androidx.graphics.opengl.egl.EGLImageKHR? eglCreateImageFromHardwareBuffer(android.opengl.EGLDisplay eglDisplay, android.hardware.HardwareBuffer hardwareBuffer);
+    method public static androidx.graphics.opengl.egl.EGLSyncKHR? eglCreateSyncKHR(android.opengl.EGLDisplay eglDisplay, int type, int[]? attributes);
+    method public static boolean eglDestroyImageKHR(android.opengl.EGLDisplay eglDisplay, androidx.graphics.opengl.egl.EGLImageKHR image);
+    method public static boolean eglDestroySyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.graphics.opengl.egl.EGLSyncKHR eglSync);
+    method public static void glEGLImageTargetTexture2DOES(int target, androidx.graphics.opengl.egl.EGLImageKHR image);
+    field public static final androidx.graphics.opengl.egl.EGLUtils.Companion Companion;
+    field public static final int EGL_SYNC_NATIVE_FENCE_ANDROID = 12612; // 0x3144
+  }
+
+  public static final class EGLUtils.Companion {
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public androidx.graphics.opengl.egl.EGLImageKHR? eglCreateImageFromHardwareBuffer(android.opengl.EGLDisplay eglDisplay, android.hardware.HardwareBuffer hardwareBuffer);
+    method public androidx.graphics.opengl.egl.EGLSyncKHR? eglCreateSyncKHR(android.opengl.EGLDisplay eglDisplay, int type, int[]? attributes);
+    method public boolean eglDestroyImageKHR(android.opengl.EGLDisplay eglDisplay, androidx.graphics.opengl.egl.EGLImageKHR image);
+    method public boolean eglDestroySyncKHR(android.opengl.EGLDisplay eglDisplay, androidx.graphics.opengl.egl.EGLSyncKHR eglSync);
+    method public void glEGLImageTargetTexture2DOES(int target, androidx.graphics.opengl.egl.EGLImageKHR image);
+  }
+
+  public final inline class EglConfigAttributes {
+    ctor public EglConfigAttributes();
+  }
+
+  public static final class EglConfigAttributes.Builder {
+    ctor @kotlin.PublishedApi internal EglConfigAttributes.Builder();
+    method @kotlin.PublishedApi internal int[] build();
+    method public void include(int[] attributes);
+    method public infix void to(int, int that);
+  }
+
+  public final class EglConfigAttributesKt {
+    method public static inline int[] EglConfigAttributes(kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.egl.EglConfigAttributes.Builder,kotlin.Unit> block);
+    method public static int[] getEglConfigAttributes1010102();
+    method public static int[] getEglConfigAttributes8888();
+    method public static int[] getEglConfigAttributesF16();
+    property public static final int[] EglConfigAttributes1010102;
+    property public static final int[] EglConfigAttributes8888;
+    property public static final int[] EglConfigAttributesF16;
+    field public static final int EglColorComponentTypeExt = 13113; // 0x3339
+    field public static final int EglColorComponentTypeFixedExt = 13114; // 0x333a
+    field public static final int EglColorComponentTypeFloatExt = 13115; // 0x333b
+  }
+
+  public final class EglException extends java.lang.RuntimeException {
+    ctor public EglException(int error, optional String msg);
+    method public int getError();
+    method public String getMsg();
+    property public final int error;
+    property public String message;
+    property public final String msg;
+  }
+
+  public final inline class EglExtensions {
+    ctor public EglExtensions();
+  }
+
+  public static final class EglExtensions.Companion {
+    method public java.util.Set<? extends java.lang.String> from(String queryString);
+  }
+
+  public final class EglExtensionsKt {
+    field public static final String EglAndroidImageNativeBuffer = "EGL_ANDROID_image_native_buffer";
+    field public static final String EglAndroidNativeFenceSync = "EGL_ANDROID_native_fence_sync";
+    field public static final String EglExtBufferAge = "EGL_EXT_buffer_age";
+    field public static final String EglExtColorSpaceDisplayP3Passthrough = "EGL_EXT_gl_colorspace_display_p3_passthrough";
+    field public static final String EglExtGlColorSpaceBt2020Pq = "EGL_EXT_gl_colorspace_bt2020_pq";
+    field public static final String EglExtGlColorSpaceScRgb = "EGL_EXT_gl_colorspace_scrgb";
+    field public static final String EglExtPixelFormatFloat = "EGL_EXT_pixel_format_float";
+    field public static final String EglImgContextPriority = "EGL_IMG_context_priority";
+    field public static final String EglKhrFenceSync = "EGL_KHR_fence_sync";
+    field public static final String EglKhrGlColorSpace = "EGL_KHR_gl_colorspace";
+    field public static final String EglKhrImage = "EGL_KHR_image";
+    field public static final String EglKhrImageBase = "EGL_KHR_image_base";
+    field public static final String EglKhrNoConfigContext = "EGL_KHR_no_config_context";
+    field public static final String EglKhrPartialUpdate = "EGL_KHR_partial_update";
+    field public static final String EglKhrSurfacelessContext = "EGL_KHR_surfaceless_context";
+    field public static final String EglKhrSwapBuffersWithDamage = "EGL_KHR_swap_buffers_with_damage";
+    field public static final String EglKhrWaitSync = "EGL_KHR_wait_sync";
+  }
+
+  public final class EglManager {
+    ctor public EglManager(optional androidx.graphics.opengl.egl.EglSpec eglSpec);
+    method public android.opengl.EGLContext createContext(android.opengl.EGLConfig config);
+    method public android.opengl.EGLSurface getCurrentDrawSurface();
+    method public android.opengl.EGLSurface getCurrentReadSurface();
+    method public android.opengl.EGLSurface getDefaultSurface();
+    method public android.opengl.EGLConfig? getEglConfig();
+    method public android.opengl.EGLContext? getEglContext();
+    method public androidx.graphics.opengl.egl.EglSpec getEglSpec();
+    method public androidx.graphics.opengl.egl.EglVersion getEglVersion();
+    method public void initialize();
+    method public boolean isExtensionSupported(String extensionName);
+    method public android.opengl.EGLConfig? loadConfig(int[] configAttributes);
+    method public boolean makeCurrent(android.opengl.EGLSurface drawSurface, optional android.opengl.EGLSurface readSurface);
+    method public boolean makeCurrent(android.opengl.EGLSurface drawSurface);
+    method public void release();
+    method public void swapAndFlushBuffers();
+    property public final android.opengl.EGLSurface currentDrawSurface;
+    property public final android.opengl.EGLSurface currentReadSurface;
+    property public final android.opengl.EGLSurface defaultSurface;
+    property public final android.opengl.EGLConfig? eglConfig;
+    property public final android.opengl.EGLContext? eglContext;
+    property public final androidx.graphics.opengl.egl.EglSpec eglSpec;
+    property public final androidx.graphics.opengl.egl.EglVersion eglVersion;
+    field public static final androidx.graphics.opengl.egl.EglManager.Companion Companion;
+  }
+
+  public static final class EglManager.Companion {
+  }
+
+  public interface EglSpec {
+    method public android.opengl.EGLContext eglCreateContext(android.opengl.EGLConfig config);
+    method public android.opengl.EGLSurface eglCreatePBufferSurface(android.opengl.EGLConfig config, int[]? configAttributes);
+    method public android.opengl.EGLSurface eglCreateWindowSurface(android.opengl.EGLConfig config, android.view.Surface surface, int[]? configAttributes);
+    method public void eglDestroyContext(android.opengl.EGLContext eglContext);
+    method public boolean eglDestroySurface(android.opengl.EGLSurface surface);
+    method public android.opengl.EGLSurface eglGetCurrentDrawSurface();
+    method public android.opengl.EGLSurface eglGetCurrentReadSurface();
+    method public int eglGetError();
+    method public androidx.graphics.opengl.egl.EglVersion eglInitialize();
+    method public boolean eglMakeCurrent(android.opengl.EGLContext context, android.opengl.EGLSurface drawSurface, android.opengl.EGLSurface readSurface);
+    method public String eglQueryString(int nameId);
+    method public boolean eglQuerySurface(android.opengl.EGLSurface surface, int attribute, int[] result, int offset);
+    method public boolean eglSwapBuffers(android.opengl.EGLSurface surface);
+    method public default String getErrorMessage();
+    method public default static String getStatusString(int error);
+    method public android.opengl.EGLConfig? loadConfig(int[] configAttributes);
+    field public static final androidx.graphics.opengl.egl.EglSpec.Companion Companion;
+    field public static final androidx.graphics.opengl.egl.EglSpec Egl14;
+  }
+
+  public static final class EglSpec.Companion {
+    method public String getStatusString(int error);
+  }
+
+  public final class EglVersion {
+    ctor public EglVersion(int major, int minor);
+    method public int component1();
+    method public int component2();
+    method public androidx.graphics.opengl.egl.EglVersion copy(int major, int minor);
+    method public int getMajor();
+    method public int getMinor();
+    property public final int major;
+    property public final int minor;
+    field public static final androidx.graphics.opengl.egl.EglVersion.Companion Companion;
+    field public static final androidx.graphics.opengl.egl.EglVersion Unknown;
+    field public static final androidx.graphics.opengl.egl.EglVersion V14;
+    field public static final androidx.graphics.opengl.egl.EglVersion V15;
+  }
+
+  public static final class EglVersion.Companion {
+  }
+
+}
+
+package androidx.graphics.surface {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class SurfaceControlCompat {
+    method protected void finalize();
+    field public static final androidx.graphics.surface.SurfaceControlCompat.Companion Companion;
+  }
+
+  public static final class SurfaceControlCompat.Builder {
+    ctor public SurfaceControlCompat.Builder(android.view.Surface surface);
+    ctor public SurfaceControlCompat.Builder(androidx.graphics.surface.SurfaceControlCompat surfaceControl);
+    method public androidx.graphics.surface.SurfaceControlCompat build();
+    method public androidx.graphics.surface.SurfaceControlCompat.Builder setDebugName(String debugName);
+  }
+
+  public static final class SurfaceControlCompat.Companion {
+  }
+
+  public static class SurfaceControlCompat.Transaction {
+    ctor public SurfaceControlCompat.Transaction();
+    method public final void addTransactionCompletedListener(androidx.graphics.surface.SurfaceControlCompat.TransactionCompletedListener listener);
+    method public final void commit();
+    method public final void delete();
+    method public final void finalize();
+    field public static final androidx.graphics.surface.SurfaceControlCompat.Transaction.Companion Companion;
+  }
+
+  public static final class SurfaceControlCompat.Transaction.Companion {
+  }
+
+  public static interface SurfaceControlCompat.TransactionCompletedListener {
+    method public void onComplete(long latchTime, long presentTime);
+  }
+
+}
+
diff --git a/graphics/graphics-core/build.gradle b/graphics/graphics-core/build.gradle
new file mode 100644
index 0000000..c421162
--- /dev/null
+++ b/graphics/graphics-core/build.gradle
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 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.
+ * 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.
+ */
+
+import androidx.build.LibraryType
+import androidx.build.Publish
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("org.jetbrains.kotlin.android")
+}
+
+dependencies {
+    api(libs.kotlinStdlib)
+    implementation 'androidx.annotation:annotation:1.2.0'
+    androidTestImplementation(libs.testExtJunit)
+    androidTestImplementation(libs.testCore)
+    androidTestImplementation(libs.testRunner)
+    androidTestImplementation(libs.testRules)
+}
+
+android {
+    defaultConfig {
+        minSdkVersion 17
+        externalNativeBuild {
+            cmake {
+                cppFlags ''
+            }
+        }
+    }
+    ndkVersion "23.1.7779620"
+    externalNativeBuild {
+        cmake {
+            path file('src/main/cpp/CMakeLists.txt')
+            version '3.22.1'
+        }
+    }
+}
+
+androidx {
+    name = "Android Graphics Core"
+    type = LibraryType.PUBLISHED_LIBRARY
+    mavenGroup = LibraryGroups.GRAPHICS
+    inceptionYear = "2021"
+    description = "Leverage graphics facilities across multiple Android platform releases"
+}
diff --git a/graphics/graphics-core/lint-baseline.xml b/graphics/graphics-core/lint-baseline.xml
new file mode 100644
index 0000000..5bcb65c
--- /dev/null
+++ b/graphics/graphics-core/lint-baseline.xml
@@ -0,0 +1,268 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 7.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (7.1.0-beta02)" variant="all" version="7.1.0-beta02">
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testConfig8888() {"
+        errorLine2="        ~~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglConfigAttributesTest.kt"
+            line="30"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testConfig1010102() {"
+        errorLine2="        ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglConfigAttributesTest.kt"
+            line="47"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testConfigF16() {"
+        errorLine2="        ~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglConfigAttributesTest.kt"
+            line="63"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testInclude() {"
+        errorLine2="        ~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglConfigAttributesTest.kt"
+            line="80"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testSupportsBufferAge() {"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="28"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testSupportBufferAgeFromPartialUpdate() {"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="33"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testSetDamage() {"
+        errorLine2="        ~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="41"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testSwapBuffersWithDamage() {"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="49"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testColorSpace() {"
+        errorLine2="        ~~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="57"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testNoConfigContext() {"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="65"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testPixelFormatFloat() {"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="73"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testScRgb() {"
+        errorLine2="        ~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="81"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testDisplayP3() {"
+        errorLine2="        ~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="89"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testHDR() {"
+        errorLine2="        ~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="97"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testContextPriority() {"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="105"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testSurfacelessContext() {"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="113"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testFenceSync() {"
+        errorLine2="        ~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="121"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testWaitSync() {"
+        errorLine2="        ~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="128"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testNativeFenceSync() {"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="133"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testExtensionsQueryStringParsing() {"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt"
+            line="141"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testDestructuringComponents() {"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglVersionTest.kt"
+            line="28"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testEquals() {"
+        errorLine2="        ~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglVersionTest.kt"
+            line="35"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testToString() {"
+        errorLine2="        ~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglVersionTest.kt"
+            line="40"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="MissingTestSizeAnnotation"
+        message="Missing test size annotation"
+        errorLine1="    fun testHashCode() {"
+        errorLine2="        ~~~~~~~~~~~~">
+        <location
+            file="src/androidTest/java/androidx/graphics/opengl/egl/EglVersionTest.kt"
+            line="45"
+            column="9"/>
+    </issue>
+
+</issues>
diff --git a/graphics/graphics-core/src/androidTest/AndroidManifest.xml b/graphics/graphics-core/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..141b3c9
--- /dev/null
+++ b/graphics/graphics-core/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  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.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="androidx.graphics.core.test">
+
+    <uses-feature android:glEsVersion="0x00020000" android:required="true" />
+    <supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
+    <supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />
+    <application>
+        <activity android:name="androidx.graphics.opengl.egl.EglTestActivity"
+            android:label="Graphics Core Test"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="androidx.graphics.opengl.GLTestActivity"
+            android:label="Graphics Core Test"
+            android:exported="true">
+        </activity>
+    </application>
+</manifest>
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLRendererTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLRendererTest.kt
new file mode 100644
index 0000000..e2a0a96
--- /dev/null
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLRendererTest.kt
@@ -0,0 +1,702 @@
+/*
+ * Copyright 2022 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.graphics.opengl
+
+import android.graphics.Bitmap
+import android.graphics.Color
+import android.graphics.PixelFormat
+import android.graphics.SurfaceTexture
+import android.media.Image
+import android.media.ImageReader
+import android.opengl.EGL14
+import android.opengl.EGLSurface
+import android.opengl.GLES20
+import android.os.Build
+import android.os.Handler
+import android.os.HandlerThread
+import android.view.PixelCopy
+import android.view.Surface
+import androidx.annotation.RequiresApi
+import androidx.graphics.opengl.egl.EglManager
+import androidx.graphics.opengl.egl.EglSpec
+import androidx.lifecycle.Lifecycle.State
+import androidx.test.core.app.ActivityScenario
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicInteger
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class GLRendererTest {
+
+    @Test
+    fun testStartAfterStop() {
+        with(GLRenderer()) {
+            start("thread1")
+            stop(true)
+            start("thread2")
+            stop(true)
+        }
+    }
+
+    @Test
+    fun testAttachBeforeStartThrows() {
+        try {
+            with(GLRenderer()) {
+                attach(
+                    Surface(SurfaceTexture(17)),
+                    10,
+                    10,
+                    object : GLRenderer.RenderCallback {
+                    override fun onDrawFrame(eglManager: EglManager) {
+                        // NO-OP
+                    }
+                })
+            }
+            fail("Start should be called first")
+        } catch (exception: IllegalStateException) {
+            // Success, attach before call to start should fail
+        }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
+    fun testRender() {
+        val latch = CountDownLatch(1)
+        val renderer = object : GLRenderer.RenderCallback {
+            override fun onDrawFrame(eglManager: EglManager) {
+                GLES20.glClearColor(1.0f, 0.0f, 1.0f, 1.0f)
+                GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
+            }
+        }
+
+        val width = 5
+        val height = 8
+        val reader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1)
+        val glRenderer = GLRenderer()
+        glRenderer.start()
+
+        val target = glRenderer.attach(reader.surface, width, height, renderer)
+        target.requestRender {
+            latch.countDown()
+        }
+
+        assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+        val plane = reader.acquireLatestImage().planes[0]
+        assertEquals(4, plane.pixelStride)
+
+        val targetColor = Color.argb(255, 255, 0, 255)
+        Api19Helpers.verifyPlaneContent(width, height, plane, targetColor)
+
+        target.detach(true)
+
+        glRenderer.stop(true)
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
+    fun testDetachExecutesPendingRequests() {
+        val latch = CountDownLatch(1)
+        val renderer = object : GLRenderer.RenderCallback {
+            override fun onDrawFrame(eglManager: EglManager) {
+                GLES20.glClearColor(1.0f, 0.0f, 1.0f, 1.0f)
+                GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
+            }
+        }
+
+        val width = 5
+        val height = 8
+        val reader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1)
+        val glRenderer = GLRenderer()
+        glRenderer.start()
+
+        val target = glRenderer.attach(reader.surface, width, height, renderer)
+        target.requestRender {
+            latch.countDown()
+        }
+        target.detach(false) // RequestRender Call should still execute
+
+        assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+        val plane = reader.acquireLatestImage().planes[0]
+        assertEquals(4, plane.pixelStride)
+
+        val targetColor = Color.argb(255, 255, 0, 255)
+        Api19Helpers.verifyPlaneContent(width, height, plane, targetColor)
+
+        glRenderer.stop(true)
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
+    fun testStopExecutesPendingRequests() {
+        val latch = CountDownLatch(1)
+        val surfaceWidth = 5
+        val surfaceHeight = 8
+        val renderer = object : GLRenderer.RenderCallback {
+            override fun onDrawFrame(eglManager: EglManager) {
+                val size = eglManager.eglSpec.querySurfaceSize(eglManager.currentDrawSurface)
+                assertEquals(surfaceWidth, size.width)
+                assertEquals(surfaceHeight, size.height)
+                GLES20.glClearColor(1.0f, 0.0f, 1.0f, 1.0f)
+                GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
+            }
+        }
+
+        val reader = ImageReader.newInstance(surfaceWidth, surfaceHeight, PixelFormat.RGBA_8888, 1)
+        val glRenderer = GLRenderer()
+        glRenderer.start()
+
+        val target = glRenderer.attach(reader.surface, surfaceWidth, surfaceHeight, renderer)
+        target.requestRender {
+            latch.countDown()
+        }
+        glRenderer.stop(false) // RequestRender call should still execute
+
+        assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+        val plane = reader.acquireLatestImage().planes[0]
+        assertEquals(4, plane.pixelStride)
+
+        val targetColor = Color.argb(255, 255, 0, 255)
+        Api19Helpers.verifyPlaneContent(surfaceWidth, surfaceHeight, plane, targetColor)
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
+    fun testDetachExecutesMultiplePendingRequests() {
+        val numRenders = 4
+        val latch = CountDownLatch(numRenders)
+        val renderCount = AtomicInteger(0)
+        val renderer = object : GLRenderer.RenderCallback {
+            override fun onDrawFrame(eglManager: EglManager) {
+                var red: Float = 0f
+                var green: Float = 0f
+                var blue: Float = 0f
+                when (renderCount.get()) {
+                    1 -> {
+                        red = 1f
+                    }
+                    2 -> {
+                        green = 1f
+                    }
+                    3 -> {
+                        blue = 1f
+                    }
+                }
+                GLES20.glClearColor(red, green, blue, 1.0f)
+                GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
+            }
+        }
+
+        val width = 5
+        val height = 8
+        val reader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1)
+        val glRenderer = GLRenderer()
+        glRenderer.start()
+
+        val target = glRenderer.attach(reader.surface, width, height, renderer)
+        // Issuing multiple requestRender calls to ensure each of them are
+        // executed even when a detach call is made
+        repeat(numRenders) {
+            target.requestRender {
+                renderCount.incrementAndGet()
+                latch.countDown()
+            }
+        }
+
+        target.detach(false) // RequestRender calls should still execute
+
+        assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+        assertEquals(numRenders, renderCount.get())
+        val plane = reader.acquireLatestImage().planes[0]
+        assertEquals(4, plane.pixelStride)
+
+        val targetColor = Color.argb(255, 0, 0, 255)
+        Api19Helpers.verifyPlaneContent(width, height, plane, targetColor)
+
+        glRenderer.stop(true)
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
+    fun testDetachCancelsPendingRequests() {
+        val latch = CountDownLatch(1)
+        val renderer = object : GLRenderer.RenderCallback {
+            override fun onDrawFrame(eglManager: EglManager) {
+                GLES20.glClearColor(1.0f, 0.0f, 1.0f, 1.0f)
+                GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
+            }
+        }
+
+        val width = 5
+        val height = 8
+        val reader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1)
+        val glRenderer = GLRenderer()
+        glRenderer.start()
+
+        val target = glRenderer.attach(reader.surface, width, height, renderer)
+        target.requestRender {
+            latch.countDown()
+        }
+        target.detach(false) // RequestRender Call should be cancelled
+
+        glRenderer.stop(true)
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
+    fun testMultipleAttachedSurfaces() {
+        val latch = CountDownLatch(2)
+        val renderer1 = object : GLRenderer.RenderCallback {
+
+            override fun onDrawFrame(eglManager: EglManager) {
+                GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f)
+                GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
+            }
+        }
+
+        val renderer2 = object : GLRenderer.RenderCallback {
+            override fun onDrawFrame(eglManager: EglManager) {
+                GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f)
+                GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
+            }
+        }
+
+        val width1 = 6
+        val height1 = 7
+
+        val width2 = 11
+        val height2 = 23
+        val reader1 = ImageReader.newInstance(width1, height1, PixelFormat.RGBA_8888, 1)
+
+        val reader2 = ImageReader.newInstance(width2, height2, PixelFormat.RGBA_8888, 1)
+
+        val glRenderer = GLRenderer()
+        glRenderer.start()
+
+        val target1 = glRenderer.attach(reader1.surface, width1, height1, renderer1)
+        val target2 = glRenderer.attach(reader2.surface, width2, height2, renderer2)
+        target1.requestRender {
+            latch.countDown()
+        }
+        target2.requestRender {
+            latch.countDown()
+        }
+
+        assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+        val plane1 = reader1.acquireLatestImage().planes[0]
+        val plane2 = reader2.acquireLatestImage().planes[0]
+
+        Api19Helpers.verifyPlaneContent(width1, height1, plane1, Color.argb(255, 255, 0, 0))
+        Api19Helpers.verifyPlaneContent(width2, height2, plane2, Color.argb(255, 0, 0, 255))
+
+        target1.detach(true)
+        target2.detach(true)
+
+        val attachLatch = CountDownLatch(1)
+        glRenderer.stop(true) {
+            attachLatch.countDown()
+        }
+
+        assertTrue(attachLatch.await(3000, TimeUnit.MILLISECONDS))
+    }
+
+    /**
+     * Helper class for test methods that refer to APIs that may not exist on earlier API levels.
+     * This must be broken out into a separate class instead of being defined within the
+     * test class as the test runner will inspect all methods + parameter types in advance.
+     * If a parameter type does not exist on a particular API level, it will crash even if
+     * there are corresponding @SdkSuppress and @RequiresApi
+     * See https://b.corp.google.com/issues/221485597
+     */
+    class Api19Helpers private constructor() {
+        companion object {
+            @RequiresApi(Build.VERSION_CODES.KITKAT)
+            fun verifyPlaneContent(width: Int, height: Int, plane: Image.Plane, targetColor: Int) {
+                val rowPadding = plane.rowStride - plane.pixelStride * width
+                var offset = 0
+                for (y in 0 until height) {
+                    for (x in 0 until width) {
+                        val red = plane.buffer[offset].toInt() and 0xff
+                        val green = plane.buffer[offset + 1].toInt() and 0xff
+                        val blue = plane.buffer[offset + 2].toInt() and 0xff
+                        val alpha = plane.buffer[offset + 3].toInt() and 0xff
+                        val packedColor = Color.argb(alpha, red, green, blue)
+                        assertEquals("Index: $x, $y", targetColor, packedColor)
+                        offset += plane.pixelStride
+                    }
+                    offset += rowPadding
+                }
+            }
+        }
+    }
+
+    @Test
+    fun testNonStartedGLRendererIsNotRunning() {
+        assertFalse(GLRenderer().isRunning())
+    }
+
+    @Test
+    fun testRepeatedStartAndStopRunningState() {
+        val glRenderer = GLRenderer()
+        assertFalse(glRenderer.isRunning())
+        glRenderer.start()
+        assertTrue(glRenderer.isRunning())
+        glRenderer.stop(true)
+        assertFalse(glRenderer.isRunning())
+        glRenderer.start()
+        assertTrue(glRenderer.isRunning())
+        glRenderer.stop(true)
+        assertFalse(glRenderer.isRunning())
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+    fun testSurfaceViewAttach() {
+        withGLTestActivity {
+            assertNotNull(surfaceView)
+
+            val latch = CountDownLatch(1)
+            val glRenderer = GLRenderer().apply { start() }
+            val target = glRenderer.attach(surfaceView, ColorRenderCallback(Color.BLUE))
+
+            target.requestRender {
+                latch.countDown()
+            }
+
+            assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+
+            val bitmap = Bitmap.createBitmap(
+                GLTestActivity.TARGET_WIDTH,
+                GLTestActivity.TARGET_HEIGHT,
+                Bitmap.Config.ARGB_8888
+            )
+
+            blockingPixelCopy(bitmap) { surfaceView.holder.surface }
+
+            assertTrue(bitmap.isAllColor(Color.BLUE))
+
+            val stopLatch = CountDownLatch(1)
+            glRenderer.stop(true) {
+                stopLatch.countDown()
+            }
+
+            assertTrue(stopLatch.await(3000, TimeUnit.MILLISECONDS))
+            // Assert that targets are detached when the GLRenderer is stopped
+            assertFalse(target.isAttached())
+        }
+    }
+
+    @Test
+    fun testTextureViewOnResizeCalled() {
+        withGLTestActivity {
+            assertNotNull(textureView)
+            val glRenderer = GLRenderer().apply { start() }
+
+            val resizeLatch = CountDownLatch(1)
+            val target = glRenderer.attach(textureView, object : GLRenderer.RenderCallback {
+                override fun onDrawFrame(eglManager: EglManager) {
+                    val size = eglManager.eglSpec.querySurfaceSize(eglManager.currentDrawSurface)
+                    assertTrue(size.width > 0)
+                    assertTrue(size.height > 0)
+                    resizeLatch.countDown()
+                }
+            })
+            target.requestRender()
+
+            assertTrue(resizeLatch.await(3000, TimeUnit.MILLISECONDS))
+
+            val detachLatch = CountDownLatch(1)
+            target.detach(false) {
+                detachLatch.countDown()
+            }
+            assertTrue(detachLatch.await(3000, TimeUnit.MILLISECONDS))
+            glRenderer.stop(true)
+        }
+    }
+
+    @Test
+    fun testSurfaceViewOnResizeCalled() {
+        withGLTestActivity {
+            assertNotNull(surfaceView)
+            val glRenderer = GLRenderer().apply { start() }
+
+            val resizeLatch = CountDownLatch(1)
+            val target = glRenderer.attach(surfaceView, object : GLRenderer.RenderCallback {
+                override fun onDrawFrame(eglManager: EglManager) {
+                    val size = eglManager.eglSpec.querySurfaceSize(eglManager.currentDrawSurface)
+                    assertTrue(size.width > 0)
+                    assertTrue(size.height > 0)
+                    resizeLatch.countDown()
+                }
+            })
+            target.requestRender()
+
+            assertTrue(resizeLatch.await(3000, TimeUnit.MILLISECONDS))
+
+            val detachLatch = CountDownLatch(1)
+            target.detach(false) {
+                detachLatch.countDown()
+            }
+            assertTrue(detachLatch.await(3000, TimeUnit.MILLISECONDS))
+            glRenderer.stop(true)
+        }
+    }
+
+    data class Size(val width: Int, val height: Int)
+
+    fun EglSpec.querySurfaceSize(eglSurface: EGLSurface): Size {
+        val result = IntArray(1)
+        eglQuerySurface(
+            eglSurface, EGL14.EGL_WIDTH, result, 0)
+        val width = result[0]
+        eglQuerySurface(
+            eglSurface, EGL14.EGL_HEIGHT, result, 0)
+        val height = result[0]
+        return Size(width, height)
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+    fun testTextureViewAttach() {
+        withGLTestActivity {
+            assertNotNull(textureView)
+
+            val latch = CountDownLatch(1)
+            val glRenderer = GLRenderer().apply { start() }
+            val target = glRenderer.attach(textureView, ColorRenderCallback(Color.BLUE))
+            target.requestRender {
+                latch.countDown()
+            }
+            assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+
+            val bitmap = Bitmap.createBitmap(
+                GLTestActivity.TARGET_WIDTH,
+                GLTestActivity.TARGET_HEIGHT,
+                Bitmap.Config.ARGB_8888
+            )
+
+            blockingPixelCopy(bitmap) { Surface(textureView.surfaceTexture) }
+            assertTrue(bitmap.isAllColor(Color.BLUE))
+
+            val stopLatch = CountDownLatch(1)
+            glRenderer.stop(true) {
+                stopLatch.countDown()
+            }
+
+            assertTrue(stopLatch.await(3000, TimeUnit.MILLISECONDS))
+            // Assert that targets are detached when the GLRenderer is stopped
+            assertFalse(target.isAttached())
+        }
+    }
+
+    @Test
+    fun testEglContextCallbackInvoked() {
+        val createdLatch = CountDownLatch(1)
+        val destroyedLatch = CountDownLatch(1)
+        val createCount = AtomicInteger()
+        val destroyCount = AtomicInteger()
+        val callback = object : GLRenderer.EglContextCallback {
+
+            override fun onEglContextCreated(eglManager: EglManager) {
+                createCount.incrementAndGet()
+                createdLatch.countDown()
+            }
+
+            override fun onEglContextDestroyed(eglManager: EglManager) {
+                destroyCount.incrementAndGet()
+                destroyedLatch.countDown()
+            }
+        }
+
+        val glRenderer = GLRenderer().apply { start() }
+        glRenderer.registerEglContextCallback(callback)
+
+        glRenderer.attach(
+            Surface(SurfaceTexture(12)),
+            10,
+            10,
+            ColorRenderCallback(Color.RED)
+        ).requestRender()
+
+        assertTrue(createdLatch.await(3000, TimeUnit.MILLISECONDS))
+        assertEquals(1, createCount.get())
+
+        glRenderer.stop(true)
+
+        assertTrue(destroyedLatch.await(3000, TimeUnit.MILLISECONDS))
+        assertEquals(1, destroyCount.get())
+    }
+
+    @Test
+    fun testEglContextCallbackInvokedBeforeStart() {
+        val createdLatch = CountDownLatch(1)
+        val destroyedLatch = CountDownLatch(1)
+        val createCount = AtomicInteger()
+        val destroyCount = AtomicInteger()
+        val callback = object : GLRenderer.EglContextCallback {
+
+            override fun onEglContextCreated(eglManager: EglManager) {
+                createCount.incrementAndGet()
+                createdLatch.countDown()
+            }
+
+            override fun onEglContextDestroyed(eglManager: EglManager) {
+                destroyCount.incrementAndGet()
+                destroyedLatch.countDown()
+            }
+        }
+
+        val glRenderer = GLRenderer()
+        // Adding a callback before the glRenderer is started should still
+        // deliver onEglRendererCreated callbacks
+        glRenderer.registerEglContextCallback(callback)
+        glRenderer.start()
+
+        glRenderer.attach(
+            Surface(SurfaceTexture(12)),
+            10,
+            10,
+            ColorRenderCallback(Color.CYAN)
+        ).requestRender()
+
+        assertTrue(createdLatch.await(3000, TimeUnit.MILLISECONDS))
+        assertEquals(1, createCount.get())
+
+        glRenderer.stop(true)
+
+        assertTrue(destroyedLatch.await(3000, TimeUnit.MILLISECONDS))
+        assertEquals(1, destroyCount.get())
+    }
+
+    @Test
+    fun testEglContextCallbackRemove() {
+        val createdLatch = CountDownLatch(1)
+        val destroyedLatch = CountDownLatch(1)
+        val createCount = AtomicInteger()
+        val destroyCount = AtomicInteger()
+        val callback = object : GLRenderer.EglContextCallback {
+
+            override fun onEglContextCreated(eglManager: EglManager) {
+                createCount.incrementAndGet()
+                createdLatch.countDown()
+            }
+
+            override fun onEglContextDestroyed(eglManager: EglManager) {
+                destroyCount.incrementAndGet()
+            }
+        }
+
+        val glRenderer = GLRenderer()
+        // Adding a callback before the glRenderer is started should still
+        // deliver onEglRendererCreated callbacks
+        glRenderer.registerEglContextCallback(callback)
+        glRenderer.start()
+
+        glRenderer.attach(
+            Surface(SurfaceTexture(12)),
+            10,
+            10,
+            ColorRenderCallback(Color.CYAN)
+        ).requestRender()
+
+        assertTrue(createdLatch.await(3000, TimeUnit.MILLISECONDS))
+        assertEquals(1, createCount.get())
+
+        glRenderer.unregisterEglContextCallback(callback)
+
+        glRenderer.stop(false) {
+            destroyedLatch.countDown()
+        }
+
+        assertTrue(destroyedLatch.await(3000, TimeUnit.MILLISECONDS))
+        assertEquals(0, destroyCount.get())
+    }
+
+    /**
+     * Helper method to create a GLTestActivity instance and progress it through the Activity
+     * lifecycle to the resumed state so we can issue rendering commands into the corresponding
+     * SurfaceView/TextureView
+     */
+    private fun withGLTestActivity(block: GLTestActivity.() -> Unit) {
+        ActivityScenario.launch(GLTestActivity::class.java).moveToState(State.RESUMED).onActivity {
+            block(it!!)
+        }
+    }
+
+    /**
+     * Helper RenderCallback that renders a solid color and invokes the provided CountdownLatch
+     * when rendering is complete
+     */
+    private class ColorRenderCallback(
+        val targetColor: Int
+    ) : GLRenderer.RenderCallback {
+
+        override fun onDrawFrame(eglManager: EglManager) {
+            GLES20.glClearColor(
+                Color.red(targetColor) / 255f,
+                Color.green(targetColor) / 255f,
+                Color.blue(targetColor) / 255f,
+                Color.alpha(targetColor) / 255f,
+            )
+            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
+        }
+    }
+
+    /**
+     * Helper method that synchronously blocks until the PixelCopy operation is complete
+     */
+    @RequiresApi(Build.VERSION_CODES.N)
+    private fun blockingPixelCopy(
+        destBitmap: Bitmap,
+        surfaceProvider: () -> Surface
+    ) {
+        val copyLatch = CountDownLatch(1)
+        val copyThread = HandlerThread("copyThread").apply { start() }
+        val copyHandler = Handler(copyThread.looper)
+        PixelCopy.request(surfaceProvider.invoke(),
+            destBitmap,
+            { copyResult ->
+                assertEquals(PixelCopy.SUCCESS, copyResult)
+                copyLatch.countDown()
+                copyThread.quit()
+            },
+            copyHandler
+        )
+        assertTrue(copyLatch.await(3000, TimeUnit.MILLISECONDS))
+    }
+
+    private fun Bitmap.isAllColor(targetColor: Int): Boolean {
+        for (i in 0 until width) {
+            for (j in 0 until height) {
+                if (getPixel(i, j) != targetColor) {
+                    return false
+                }
+            }
+        }
+        return true
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLTestActivity.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLTestActivity.kt
new file mode 100644
index 0000000..103c36b
--- /dev/null
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLTestActivity.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 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.graphics.opengl
+
+import android.app.Activity
+import android.os.Bundle
+import android.view.SurfaceView
+import android.view.TextureView
+import android.widget.LinearLayout
+
+class GLTestActivity : Activity() {
+
+    companion object {
+        const val TARGET_WIDTH = 30
+        const val TARGET_HEIGHT = 20
+    }
+
+    lateinit var surfaceView: SurfaceView
+    lateinit var textureView: TextureView
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        surfaceView = SurfaceView(this)
+        textureView = TextureView(this)
+        val ll = LinearLayout(this).apply {
+            orientation = LinearLayout.VERTICAL
+            weightSum = 2f
+        }
+        val layoutParams = LinearLayout.LayoutParams(TARGET_WIDTH, TARGET_HEIGHT)
+
+        ll.addView(surfaceView, layoutParams)
+        ll.addView(textureView, layoutParams)
+
+        setContentView(ll)
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglConfigAttributesTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglConfigAttributesTest.kt
new file mode 100644
index 0000000..5a5ea46
--- /dev/null
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglConfigAttributesTest.kt
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ * 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.graphics.opengl.egl
+
+import android.opengl.EGL14
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class EglConfigAttributesTest {
+
+    @Test
+    fun testConfig8888() {
+        with(EglConfigAttributes8888.attrs) {
+            assertTrue(find(EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT))
+            assertTrue(find(EGL14.EGL_RED_SIZE, 8))
+            assertTrue(find(EGL14.EGL_GREEN_SIZE, 8))
+            assertTrue(find(EGL14.EGL_BLUE_SIZE, 8))
+            assertTrue(find(EGL14.EGL_ALPHA_SIZE, 8))
+            assertTrue(find(EGL14.EGL_DEPTH_SIZE, 0))
+            assertTrue(find(EGL14.EGL_CONFIG_CAVEAT, EGL14.EGL_NONE))
+            assertTrue(find(EGL14.EGL_STENCIL_SIZE, 0))
+            assertTrue(find(EGL14.EGL_SURFACE_TYPE, EGL14.EGL_WINDOW_BIT))
+            assertEquals(this[size - 1], EGL14.EGL_NONE)
+            assertEquals(19, size)
+        }
+    }
+
+    @Test
+    fun testConfig1010102() {
+        with(EglConfigAttributes1010102.attrs) {
+            assertTrue(find(EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT))
+            assertTrue(find(EGL14.EGL_RED_SIZE, 10))
+            assertTrue(find(EGL14.EGL_GREEN_SIZE, 10))
+            assertTrue(find(EGL14.EGL_BLUE_SIZE, 10))
+            assertTrue(find(EGL14.EGL_ALPHA_SIZE, 2))
+            assertTrue(find(EGL14.EGL_DEPTH_SIZE, 0))
+            assertTrue(find(EGL14.EGL_STENCIL_SIZE, 0))
+            assertTrue(find(EGL14.EGL_SURFACE_TYPE, EGL14.EGL_WINDOW_BIT))
+            assertEquals(this[size - 1], EGL14.EGL_NONE)
+            assertEquals(17, size)
+        }
+    }
+
+    @Test
+    fun testConfigF16() {
+        with(EglConfigAttributesF16.attrs) {
+            assertTrue(find(EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT))
+            assertTrue(find(EglColorComponentTypeExt, EglColorComponentTypeFloatExt))
+            assertTrue(find(EGL14.EGL_RED_SIZE, 16))
+            assertTrue(find(EGL14.EGL_GREEN_SIZE, 16))
+            assertTrue(find(EGL14.EGL_BLUE_SIZE, 16))
+            assertTrue(find(EGL14.EGL_ALPHA_SIZE, 16))
+            assertTrue(find(EGL14.EGL_DEPTH_SIZE, 0))
+            assertTrue(find(EGL14.EGL_STENCIL_SIZE, 0))
+            assertTrue(find(EGL14.EGL_SURFACE_TYPE, EGL14.EGL_WINDOW_BIT))
+            assertEquals(this[size - 1], EGL14.EGL_NONE)
+            assertEquals(19, size)
+        }
+    }
+
+    @Test
+    fun testInclude() {
+        // Verify that custom config that uses an include initially and overwrites
+        // individual values is handled appropriately even if the config is technically invalid
+        val customConfig = EglConfigAttributes {
+            include(EglConfigAttributes8888)
+            EGL14.EGL_RED_SIZE to 27
+            EglColorComponentTypeExt to EglColorComponentTypeFloatExt
+            EGL14.EGL_STENCIL_SIZE to 32
+        }
+
+        with(customConfig.attrs) {
+            assertTrue(find(EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT))
+            assertTrue(find(EGL14.EGL_RED_SIZE, 27))
+            assertTrue(find(EglColorComponentTypeExt, EglColorComponentTypeFloatExt))
+            assertTrue(find(EGL14.EGL_STENCIL_SIZE, 32))
+            assertEquals(this[size - 1], EGL14.EGL_NONE)
+            assertEquals(21, size)
+        }
+    }
+
+    private fun IntArray.find(key: Int, value: Int): Boolean {
+        // size - 1 to skip trailing EGL_NONE
+        for (i in 0 until this.size - 1 step 2) {
+            if (this[i] == key) {
+                return this[i + 1] == value
+            }
+        }
+        return false
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt
new file mode 100644
index 0000000..7396807
--- /dev/null
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglExtensionsTest.kt
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ * 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.graphics.opengl.egl
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class EglExtensionsTest {
+
+    @Test
+    fun testSupportsBufferAge() {
+        assertTrue(EglExtensions(setOf("EGL_EXT_buffer_age")).isExtensionSupported(EglExtBufferAge))
+    }
+
+    @Test
+    fun testSupportBufferAgeFromPartialUpdate() {
+        // Buffer age can be supported from either EGL_EXT_buffer_age or EGL_KHR_partial_update
+        assertTrue(
+            EglExtensions(setOf("EGL_KHR_partial_update")).isExtensionSupported(EglKhrPartialUpdate)
+        )
+    }
+
+    @Test
+    fun testSetDamage() {
+        assertTrue(
+            EglExtensions(setOf("EGL_KHR_partial_update"))
+                .isExtensionSupported(EglKhrPartialUpdate)
+        )
+    }
+
+    @Test
+    fun testSwapBuffersWithDamage() {
+        assertTrue(
+            EglExtensions(setOf("EGL_KHR_swap_buffers_with_damage"))
+                .isExtensionSupported(EglKhrSwapBuffersWithDamage)
+        )
+    }
+
+    @Test
+    fun testColorSpace() {
+        assertTrue(
+            EglExtensions(setOf("EGL_KHR_gl_colorspace"))
+                .isExtensionSupported(EglKhrGlColorSpace)
+        )
+    }
+
+    @Test
+    fun testNoConfigContext() {
+        assertTrue(
+            EglExtensions(setOf("EGL_KHR_no_config_context"))
+                .isExtensionSupported(EglKhrNoConfigContext)
+        )
+    }
+
+    @Test
+    fun testPixelFormatFloat() {
+        assertTrue(
+            EglExtensions(setOf("EGL_EXT_pixel_format_float"))
+                .isExtensionSupported(EglExtPixelFormatFloat)
+        )
+    }
+
+    @Test
+    fun testScRgb() {
+        assertTrue(
+            EglExtensions(setOf("EGL_EXT_gl_colorspace_scrgb"))
+                .isExtensionSupported(EglExtGlColorSpaceScRgb)
+        )
+    }
+
+    @Test
+    fun testDisplayP3() {
+        assertTrue(
+            EglExtensions(setOf("EGL_EXT_gl_colorspace_display_p3_passthrough"))
+                .isExtensionSupported(EglExtColorSpaceDisplayP3Passthrough)
+        )
+    }
+
+    @Test
+    fun testHDR() {
+        assertTrue(
+            EglExtensions(setOf("EGL_EXT_gl_colorspace_bt2020_pq"))
+                .isExtensionSupported(EglExtGlColorSpaceBt2020Pq)
+        )
+    }
+
+    @Test
+    fun testContextPriority() {
+        assertTrue(
+            EglExtensions(setOf("EGL_IMG_context_priority"))
+                .isExtensionSupported(EglImgContextPriority)
+        )
+    }
+
+    @Test
+    fun testSurfacelessContext() {
+        assertTrue(
+            EglExtensions(setOf("EGL_KHR_surfaceless_context"))
+                .isExtensionSupported(EglKhrSurfacelessContext)
+        )
+    }
+
+    @Test
+    fun testFenceSync() {
+        assertTrue(
+            EglExtensions(setOf("EGL_KHR_fence_sync")).isExtensionSupported(EglKhrFenceSync)
+        )
+    }
+
+    @Test
+    fun testWaitSync() {
+        assertTrue(EglExtensions(setOf("EGL_KHR_wait_sync")).isExtensionSupported(EglKhrWaitSync))
+    }
+
+    @Test
+    fun testNativeFenceSync() {
+        assertTrue(
+            EglExtensions(setOf("EGL_ANDROID_native_fence_sync"))
+                .isExtensionSupported(EglAndroidNativeFenceSync)
+        )
+    }
+
+    @Test
+    fun testExtensionsQueryStringParsing() {
+        val extensionQuery = "EGL_EXT_buffer_age " +
+            "EGL_KHR_partial_update " +
+            "EGL_KHR_swap_buffers_with_damage " +
+            "EGL_KHR_gl_colorspace " +
+            "EGL_KHR_no_config_context " +
+            "EGL_EXT_pixel_format_float " +
+            "EGL_EXT_gl_colorspace_scrgb " +
+            "EGL_EXT_gl_colorspace_display_p3_passthrough " +
+            "EGL_EXT_gl_colorspace_bt2020_pq " +
+            "EGL_IMG_context_priority " +
+            "EGL_KHR_surfaceless_context " +
+            "EGL_KHR_fence_sync " +
+            "EGL_KHR_wait_sync " +
+            "EGL_ANDROID_native_fence_sync "
+        with(EglExtensions.from(extensionQuery)) {
+            assertTrue(isExtensionSupported(EglExtBufferAge))
+            assertTrue(isExtensionSupported(EglKhrPartialUpdate))
+            assertTrue(isExtensionSupported(EglKhrSwapBuffersWithDamage))
+            assertTrue(isExtensionSupported(EglKhrGlColorSpace))
+            assertTrue(isExtensionSupported(EglKhrNoConfigContext))
+            assertTrue(isExtensionSupported(EglExtPixelFormatFloat))
+            assertTrue(isExtensionSupported(EglExtGlColorSpaceScRgb))
+            assertTrue(isExtensionSupported(EglExtColorSpaceDisplayP3Passthrough))
+            assertTrue(isExtensionSupported(EglExtGlColorSpaceBt2020Pq))
+            assertTrue(isExtensionSupported(EglImgContextPriority))
+            assertTrue(isExtensionSupported(EglKhrSurfacelessContext))
+            assertTrue(isExtensionSupported(EglKhrFenceSync))
+            assertTrue(isExtensionSupported(EglKhrWaitSync))
+            assertTrue(isExtensionSupported(EglAndroidNativeFenceSync))
+        }
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglManagerTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglManagerTest.kt
new file mode 100644
index 0000000..ce701ef
--- /dev/null
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglManagerTest.kt
@@ -0,0 +1,474 @@
+/*
+ * 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.
+ * 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.graphics.opengl.egl
+
+import android.graphics.Color
+import android.graphics.PixelFormat
+import android.graphics.SurfaceTexture
+import android.hardware.HardwareBuffer
+import android.media.ImageReader
+import android.opengl.EGL14
+import android.opengl.EGLSurface
+import android.opengl.GLES20
+import android.os.Build
+import android.view.Surface
+import androidx.annotation.RequiresApi
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNotEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+import kotlin.concurrent.thread
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class EglManagerTest {
+
+    @Test
+    fun testInitializeAndRelease() {
+        testEglManager {
+            initialize()
+            val config = loadConfig(EglConfigAttributes8888)?.also {
+                createContext(it)
+            }
+            if (config == null) {
+                fail("Config 8888 should be supported")
+            }
+            // Even though EGL v 1.5 was introduced in API level 29 not all devices will advertise
+            // support for it. However, all devices should at least support EGL v 1.4
+            assertTrue(
+                "Unexpected EGL version, received $eglVersion",
+                eglVersion == EglVersion.V14 || eglVersion == EglVersion.V15
+            )
+            assertNotNull(eglContext)
+            assertNotNull(eglConfig)
+        }
+    }
+
+    @Test
+    fun testMultipleInitializeCallsIgnored() {
+        testEglManager {
+            initialize()
+            loadConfig(EglConfigAttributes8888)?.also {
+                createContext(it)
+            }
+            val currentContext = eglContext
+            val currentConfig = eglConfig
+            assertNotEquals(EGL14.EGL_NO_CONTEXT, currentContext)
+            // Subsequent calls to initialize should be ignored
+            // and the current EglContext should be the same as the previous call
+            initialize()
+            assertTrue(currentContext === eglContext)
+            assertTrue(currentConfig === eglConfig)
+        }
+    }
+
+    @Test
+    fun testMultipleReleaseCallsIgnored() {
+        testEglManager {
+            initialize()
+            loadConfig(EglConfigAttributes8888)?.also {
+                createContext(it)
+            }
+            // Multiple attempts to release should act as no-ops, i.e. we should not crash
+            // and the corresponding context should be nulled out
+            release()
+            assertEquals(EGL14.EGL_NO_CONTEXT, eglContext)
+
+            release()
+            assertEquals(EGL14.EGL_NO_CONTEXT, eglContext)
+        }
+    }
+
+    @Test
+    fun testDefaultSurface() {
+        testEglManager {
+            initialize()
+
+            assertEquals(defaultSurface, EGL14.EGL_NO_SURFACE)
+            assertEquals(currentDrawSurface, EGL14.EGL_NO_SURFACE)
+            assertEquals(currentReadSurface, EGL14.EGL_NO_SURFACE)
+
+            val config = loadConfig(EglConfigAttributes8888)
+
+            if (config == null) {
+                fail("Config 8888 should be supported")
+            }
+
+            createContext(config!!)
+
+            if (isExtensionSupported(EglKhrSurfacelessContext)) {
+                assertEquals(defaultSurface, EGL14.EGL_NO_SURFACE)
+            } else {
+                assertNotEquals(defaultSurface, EGL14.EGL_NO_SURFACE)
+            }
+
+            assertEquals(currentDrawSurface, defaultSurface)
+            assertEquals(currentReadSurface, defaultSurface)
+
+            release()
+
+            assertEquals(defaultSurface, EGL14.EGL_NO_SURFACE)
+            assertEquals(currentDrawSurface, EGL14.EGL_NO_SURFACE)
+            assertEquals(currentReadSurface, EGL14.EGL_NO_SURFACE)
+        }
+    }
+
+    @Test
+    fun testDefaultSurfaceWithoutSurfacelessContext() {
+        // Create a new EGL Spec instance that does not support the
+        // EglKhrSurfacelessContext extension in order to verify
+        // the fallback support of initializing the current surface
+        // to a PBuffer instead of EGL14.EGL_NO_SURFACE
+        val wrappedEglSpec = object : EglSpec by EglSpec.Egl14 {
+            override fun eglQueryString(nameId: Int): String {
+                val queryString = EglSpec.Egl14.eglQueryString(nameId)
+                return if (nameId == EGL14.EGL_EXTENSIONS) {
+                    // Parse the space separated string of EGL extensions into a set
+                    val set = HashSet<String>().apply {
+                        addAll(queryString.split(' '))
+                    }
+                    // Remove EglKhrSurfacelessContext if it exists
+                    // and repack the set into a space separated string
+                    set.remove(EglKhrSurfacelessContext)
+                    StringBuilder().let {
+                        for (entry in set) {
+                            it.append(entry)
+                            it.append(' ')
+                        }
+                        it.toString()
+                    }
+                } else {
+                    queryString
+                }
+            }
+        }
+
+        testEglManager(wrappedEglSpec) {
+            initialize()
+
+            // Verify that the wrapped EGL spec implementation in fact does not
+            // advertise support for EglKhrSurfacelessContext
+            assertFalse(isExtensionSupported(EglKhrSurfacelessContext))
+
+            assertEquals(defaultSurface, EGL14.EGL_NO_SURFACE)
+            assertEquals(currentDrawSurface, EGL14.EGL_NO_SURFACE)
+            assertEquals(currentReadSurface, EGL14.EGL_NO_SURFACE)
+
+            val config = loadConfig(EglConfigAttributes8888)
+
+            if (config == null) {
+                fail("Config 8888 should be supported")
+            }
+
+            // Create context at this point should fallback of eglCreatePBufferSurface
+            // instead of EGL_NO_SURFACE as a result of no longer advertising support
+            // for EglKhrSurfacelessContext
+            createContext(config!!)
+
+            assertNotEquals(defaultSurface, EGL14.EGL_NO_SURFACE)
+            assertEquals(currentDrawSurface, defaultSurface)
+            assertEquals(currentReadSurface, defaultSurface)
+
+            release()
+
+            assertEquals(defaultSurface, EGL14.EGL_NO_SURFACE)
+            assertEquals(currentDrawSurface, EGL14.EGL_NO_SURFACE)
+            assertEquals(currentReadSurface, EGL14.EGL_NO_SURFACE)
+        }
+    }
+
+    @Test
+    fun testCreatePBufferSurface() {
+        testEglManager {
+            initialize()
+
+            assertEquals(defaultSurface, EGL14.EGL_NO_SURFACE)
+            assertEquals(currentDrawSurface, EGL14.EGL_NO_SURFACE)
+            assertEquals(currentReadSurface, EGL14.EGL_NO_SURFACE)
+
+            val config = loadConfig(EglConfigAttributes8888)
+
+            if (config == null) {
+                fail("Config 8888 should be supported")
+            }
+            createContext(config!!)
+
+            val pBuffer = eglSpec.eglCreatePBufferSurface(
+                config,
+                EglConfigAttributes {
+                    EGL14.EGL_WIDTH to 1
+                    EGL14.EGL_HEIGHT to 1
+                })
+
+            makeCurrent(pBuffer)
+
+            assertNotEquals(EGL14.EGL_NO_SURFACE, currentReadSurface)
+            assertNotEquals(EGL14.EGL_NO_SURFACE, currentDrawSurface)
+            assertNotEquals(EGL14.EGL_NO_SURFACE, pBuffer)
+
+            assertEquals(pBuffer, currentReadSurface)
+            assertEquals(pBuffer, currentDrawSurface)
+
+            eglSpec.eglDestroySurface(pBuffer)
+            release()
+        }
+    }
+
+    @Test
+    fun testCreateWindowSurfaceDefault() {
+        testEglManager {
+            initialize()
+
+            val config = loadConfig(EglConfigAttributes8888)
+            if (config == null) {
+                fail("Config 8888 should be supported")
+            }
+
+            createContext(config!!)
+
+            val surface = Surface(SurfaceTexture(42))
+            // Create a window surface with the default attributes
+            val eglSurface = eglSpec.eglCreateWindowSurface(config, surface, null)
+            assertNotEquals(EGL14.EGL_NO_SURFACE, eglSurface)
+            eglSpec.eglDestroySurface(eglSurface)
+
+            release()
+        }
+    }
+
+    private fun EglSpec.isSingleBufferedSurface(surface: EGLSurface): Boolean {
+        return if (surface == EGL14.EGL_NO_SURFACE) {
+            false
+        } else {
+            val result = IntArray(1)
+            val queryResult = eglQuerySurface(
+                surface, EGL14.EGL_RENDER_BUFFER, result, 0)
+            queryResult && result[0] == EGL14.EGL_SINGLE_BUFFER
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
+    @Test
+    fun testSurfaceContentsWithBackBuffer() {
+        verifySurfaceContentsWithWindowConfig()
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
+    @Test
+    fun testSurfaceContentsWithFrontBuffer() {
+        verifySurfaceContentsWithWindowConfig(true)
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
+    private fun verifySurfaceContentsWithWindowConfig(
+        singleBuffered: Boolean = false
+    ) {
+        testEglManager {
+            initialize()
+            val config = loadConfig(EglConfigAttributes8888)
+            if (config == null) {
+                fail("Config 8888 should be supported")
+            }
+            createContext(config!!)
+
+            val width = 8
+            val height = 5
+            val targetColor = Color.RED
+            val imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1)
+            var canRender = false
+
+            thread {
+                canRender = drawSurface(imageReader.surface, targetColor, singleBuffered)
+            }.join()
+
+            try {
+                if (canRender) {
+                    val image = imageReader.acquireLatestImage()
+                    val plane = image.planes[0]
+                    assertEquals(4, plane.pixelStride)
+
+                    val pixelStride = plane.pixelStride
+                    val rowStride = plane.rowStride
+                    val rowPadding = rowStride - pixelStride * width
+                    var offset = 0
+                    for (y in 0 until height) {
+                        for (x in 0 until width) {
+                            val red = plane.buffer[offset].toInt() and 0xff
+                            val green = plane.buffer[offset + 1].toInt() and 0xff
+                            val blue = plane.buffer[offset + 2].toInt() and 0xff
+                            val alpha = plane.buffer[offset + 3].toInt() and 0xff
+                            val packedColor = Color.argb(alpha, red, green, blue)
+                            assertEquals("Index: " + x + ", " + y, targetColor, packedColor)
+                            offset += pixelStride
+                        }
+                        offset += rowPadding
+                    }
+                }
+            } finally {
+                imageReader.close()
+                release()
+            }
+        }
+    }
+
+    private fun drawSurface(
+        surface: Surface,
+        color: Int,
+        singleBuffered: Boolean
+    ): Boolean {
+        var canRender = false
+        testEglManager {
+            initialize()
+            val config = loadConfig(EglConfigAttributes8888)
+            if (config == null) {
+                fail("Config 8888 should be supported")
+            }
+            createContext(config!!)
+            val configAttributes = if (singleBuffered) {
+                EglConfigAttributes {
+                    EGL14.EGL_RENDER_BUFFER to EGL14.EGL_SINGLE_BUFFER
+                }
+            } else {
+                null
+            }
+            val eglSurface = eglSpec.eglCreateWindowSurface(config, surface, configAttributes)
+            // Skip tests of the device does not support EGL_SINGLE_BUFFER
+            canRender = !singleBuffered || eglSpec.isSingleBufferedSurface(eglSurface)
+            if (canRender) {
+                makeCurrent(eglSurface)
+                assertEquals("Make current failed", EGL14.EGL_SUCCESS, eglSpec.eglGetError())
+                GLES20.glClearColor(
+                    Color.red(color) / 255f,
+                    Color.green(color) / 255f,
+                    Color.blue(color) / 255f,
+                    Color.alpha(color) / 255f
+                )
+                GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
+                swapAndFlushBuffers()
+                assertEquals("Swapbuffers failed", EGL14.EGL_SUCCESS, eglSpec.eglGetError())
+            }
+
+            eglSpec.eglDestroySurface(eglSurface)
+            release()
+        }
+        return canRender
+    }
+
+    @Test
+    fun testEglGetNativeClientBufferANDROIDSupported() {
+        testEglManager {
+            val khrImageBaseSupported =
+                isExtensionSupported(EglKhrImageBase)
+            val androidImageNativeBufferSupported =
+                isExtensionSupported(EglAndroidImageNativeBuffer)
+            // According to EGL spec both these extensions are required in order to support
+            // eglGetNativeClientBufferAndroid
+            if (khrImageBaseSupported && androidImageNativeBufferSupported) {
+                assertTrue(EGLUtilsBindings.nSupportsEglGetNativeClientBufferAndroid())
+            }
+        }
+    }
+
+    @Test
+    fun testEglCreateAndDestroyImageKHRSupported() {
+        testEglManager {
+            if (isExtensionSupported(EglKhrImageBase)) {
+                assertTrue(EGLUtilsBindings.nSupportsEglCreateImageKHR())
+                assertTrue(EGLUtilsBindings.nSupportsEglDestroyImageKHR())
+            }
+        }
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    fun testEglCreateAndDestroyImageKHR() {
+        testEglManager {
+            if (isExtensionSupported(EglKhrImageBase)) {
+                val display = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY)
+                val hardwareBuffer = HardwareBuffer.create(
+                    10,
+                    10,
+                    PixelFormat.RGBA_8888,
+                    1,
+                    HardwareBuffer.USAGE_GPU_COLOR_OUTPUT
+                )
+                val image = EGLUtils.eglCreateImageFromHardwareBuffer(display, hardwareBuffer)
+                assertNotNull(image)
+                assertTrue(EGLUtils.eglDestroyImageKHR(display, image!!))
+            }
+        }
+    }
+
+    @Test
+    fun testGlImageTargetTexture2DOESSupported() {
+        testEglManager {
+            // According to EGL spec *EITHER* EGL_KHR_image_base or EGL_KHR_image
+            // indicate that the eglImageTargetTexture2DOES method is supported on this device
+            if (isExtensionSupported(EglKhrImageBase) || isExtensionSupported(EglKhrImage)) {
+                assertTrue(EGLUtilsBindings.nSupportsGlImageTargetTexture2DOES())
+            }
+        }
+    }
+
+    @Test
+    fun testEglCreateAndDestroySyncKHRSupported() {
+        testEglManager {
+            if (isExtensionSupported(EglKhrFenceSync)) {
+                assertTrue(EGLUtilsBindings.nSupportsEglCreateSyncKHR())
+                assertTrue(EGLUtilsBindings.nSupportsEglDestroySyncKHR())
+            }
+        }
+    }
+
+    @Test
+    fun testEglCreateAndDestroySyncKHR() {
+        testEglManager {
+            if (isExtensionSupported(EglKhrFenceSync)) {
+                val display = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY)
+                val sync = EGLUtils.eglCreateSyncKHR(display,
+                    EGLUtils.EGL_SYNC_NATIVE_FENCE_ANDROID, null)
+                assertNotNull(sync)
+                assertTrue(EGLUtils.eglDestroySyncKHR(display, sync!!))
+            }
+        }
+    }
+
+    /**
+     * Helper method to ensure EglManager has the corresponding release calls
+     * made to it and verifies that no exceptions were thrown as part of the test.
+     */
+    private fun testEglManager(
+        eglSpec: EglSpec = EglSpec.Egl14,
+        block: EglManager.() -> Unit = {}
+    ) {
+        with(EglManager(eglSpec)) {
+            assertEquals(EglVersion.Unknown, eglVersion)
+            assertEquals(EGL14.EGL_NO_CONTEXT, eglContext)
+            block()
+            release()
+            assertEquals(EglVersion.Unknown, eglVersion)
+            assertEquals(EGL14.EGL_NO_CONTEXT, eglContext)
+        }
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglTestActivity.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglTestActivity.kt
new file mode 100644
index 0000000..35c4355
--- /dev/null
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglTestActivity.kt
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ * 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.graphics.opengl.egl
+
+import android.animation.ValueAnimator
+import android.app.Activity
+import android.opengl.EGL14
+import android.opengl.EGLConfig
+import android.opengl.EGLSurface
+import android.opengl.GLES20
+import android.os.Bundle
+import android.view.Surface
+import android.view.SurfaceView
+import android.view.TextureView
+import android.widget.LinearLayout
+import androidx.graphics.opengl.GLRenderer
+import androidx.graphics.opengl.GLRenderer.RenderTarget
+import java.util.concurrent.atomic.AtomicInteger
+
+const val TAG: String = "EGLTestActivity"
+
+class EglTestActivity : Activity() {
+
+    private val mGLRenderer = GLRenderer()
+    private val mParam = AtomicInteger()
+    private val mRenderer1 = object : GLRenderer.RenderCallback {
+        override fun onSurfaceCreated(
+            spec: EglSpec,
+            config: EGLConfig,
+            surface: Surface,
+            width: Int,
+            height: Int
+        ): EGLSurface {
+            val attrs = EglConfigAttributes {
+                EGL14.EGL_RENDER_BUFFER to EGL14.EGL_SINGLE_BUFFER
+            }
+            return spec.eglCreateWindowSurface(config, surface, attrs)
+        }
+
+        override fun onDrawFrame(eglManager: EglManager) {
+            val red = mParam.toFloat() / 100f
+            GLES20.glClearColor(red, 0.0f, 0.0f, 1.0f)
+            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
+        }
+    }
+
+    private val mRenderer2 = object : GLRenderer.RenderCallback {
+        override fun onDrawFrame(eglManager: EglManager) {
+            val blue = mParam.toFloat() / 100f
+            GLES20.glClearColor(0.0f, 0.0f, blue, 1.0f)
+            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
+        }
+    }
+
+    private lateinit var mSurfaceView: SurfaceView
+    private lateinit var mTextureView: TextureView
+    private lateinit var mRenderTarget1: RenderTarget
+    private lateinit var mRenderTarget2: RenderTarget
+
+    private var mAnimator: ValueAnimator? = null
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        mGLRenderer.start()
+
+        mAnimator = ValueAnimator.ofFloat(0.0f, 1.0f).apply {
+            duration = 3000
+            repeatCount = ValueAnimator.INFINITE
+            repeatMode = ValueAnimator.REVERSE
+            addUpdateListener {
+                mParam.set(((it.animatedValue as Float) * 100).toInt())
+                mRenderTarget1.requestRender()
+                mRenderTarget2.requestRender()
+            }
+            start()
+        }
+
+        val container = LinearLayout(this).apply {
+            orientation = LinearLayout.VERTICAL
+            weightSum = 2f
+        }
+        mSurfaceView = SurfaceView(this)
+        mTextureView = TextureView(this)
+
+        val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0).apply {
+            weight = 1f
+        }
+
+        mRenderTarget1 = mGLRenderer.attach(mSurfaceView, mRenderer1)
+        mRenderTarget2 = mGLRenderer.attach(mTextureView, mRenderer2)
+
+        container.addView(mSurfaceView, params)
+        container.addView(mTextureView, params)
+
+        setContentView(container)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        if (!mRenderTarget1.isAttached()) {
+            mRenderTarget1 = mGLRenderer.attach(mSurfaceView, mRenderer1)
+        }
+
+        if (!mRenderTarget2.isAttached()) {
+            mRenderTarget2 = mGLRenderer.attach(mTextureView, mRenderer2)
+        }
+    }
+
+    override fun onPause() {
+        super.onPause()
+        mRenderTarget1.detach(true)
+        mRenderTarget2.detach(true)
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+        mAnimator?.cancel()
+        mGLRenderer.stop(true)
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglVersionTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglVersionTest.kt
new file mode 100644
index 0000000..87e2208
--- /dev/null
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EglVersionTest.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ * 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.graphics.opengl.egl
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class EglVersionTest {
+
+    @Test
+    fun testDestructuringComponents() {
+        val (major, minor) = EglVersion(8, 3)
+        assertEquals(8, major)
+        assertEquals(3, minor)
+    }
+
+    @Test
+    fun testEquals() {
+        assertEquals(EglVersion(2, 9), EglVersion(2, 9))
+    }
+
+    @Test
+    fun testToString() {
+        assertEquals("EGL version 5.9", EglVersion(5, 9).toString())
+    }
+
+    @Test
+    fun testHashCode() {
+        val hashCode = 31 * 8 + 4
+        assertEquals(hashCode, EglVersion(8, 4).hashCode())
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlCompatTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlCompatTest.kt
new file mode 100644
index 0000000..29dd73a
--- /dev/null
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlCompatTest.kt
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ * 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.graphics.surface
+
+import android.os.Build
+import android.os.SystemClock
+import android.view.Surface
+import android.view.SurfaceControl
+import androidx.annotation.RequiresApi
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@RequiresApi(Build.VERSION_CODES.Q)
+@SdkSuppress(minSdkVersion = 29)
+class SurfaceControlCompatTest {
+
+    @Test
+    fun testCreateFromWindow() {
+        var surfaceControl = SurfaceControl.Builder()
+            .setName("SurfaceControlCompact_createFromWindow")
+            .build()
+        try {
+            SurfaceControlCompat.Builder(Surface(surfaceControl))
+                .setDebugName("SurfaceControlCompatTest")
+                .build()
+        } catch (e: IllegalArgumentException) {
+            fail()
+        }
+    }
+
+    @Test
+    fun testSurfaceControlCompatBuilder_surfaceControlParent() {
+        val surfaceControl = SurfaceControl.Builder()
+            .setName("SurfaceControlCompact_createFromWindow")
+            .build()
+        try {
+            SurfaceControlCompat.Builder(
+                SurfaceControlCompat(
+                    Surface(surfaceControl),
+                    null,
+                    "SurfaceControlCompatTest"
+                )
+            )
+                .setDebugName("SurfaceControlCompatTest")
+                .build()
+        } catch (e: IllegalArgumentException) {
+            fail()
+        }
+    }
+
+    @Test
+    fun testSurfaceControlCompatBuilder_surfaceParent() {
+        val surfaceControl = SurfaceControl.Builder()
+            .setName("SurfaceControlCompact_createFromWindow")
+            .build()
+        try {
+            SurfaceControlCompat.Builder(Surface(surfaceControl))
+                .setDebugName("SurfaceControlCompatTest")
+                .build()
+        } catch (e: IllegalArgumentException) {
+            fail()
+        }
+    }
+
+    @Test
+    fun testSurfaceTransactionCreate() {
+        try {
+            SurfaceControlCompat.Transaction()
+        } catch (e: java.lang.IllegalArgumentException) {
+            fail()
+        }
+    }
+
+    class TransactionOnCompleteListener : SurfaceControlCompat.TransactionCompletedListener {
+        var mCallbackTime = -1L
+        var mLatchTime = -1L
+        var mPresentTime = -1L
+        var mLatch = CountDownLatch(1)
+
+        override fun onComplete(latchTime: Long, presentTime: Long) {
+            mCallbackTime = SystemClock.elapsedRealtime()
+            mLatchTime = latchTime
+            mPresentTime = presentTime
+            mLatch.countDown()
+        }
+    }
+
+    @Test
+    fun testSurfaceTransactionOnCompleteCallback() {
+        val transaction = SurfaceControlCompat.Transaction()
+        val listener = TransactionOnCompleteListener()
+        transaction.addTransactionCompletedListener(listener)
+        transaction.commit()
+
+        listener.mLatch.await(1, TimeUnit.SECONDS)
+
+        assertEquals(0, listener.mLatch.count)
+        assertTrue(listener.mCallbackTime > 0)
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/AndroidManifest.xml b/graphics/graphics-core/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..0082b69
--- /dev/null
+++ b/graphics/graphics-core/src/main/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  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.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="androidx.graphics.core">
+
+</manifest>
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/androidx/graphics/androidx-graphics-graphics-core-documentation.md b/graphics/graphics-core/src/main/androidx/graphics/androidx-graphics-graphics-core-documentation.md
new file mode 100644
index 0000000..ffaf9e0
--- /dev/null
+++ b/graphics/graphics-core/src/main/androidx/graphics/androidx-graphics-graphics-core-documentation.md
@@ -0,0 +1,5 @@
+# Module root
+
+AndroidX Graphics Core
+
+# Support classes for building applications that leverage more advanced graphics facilities
diff --git a/graphics/graphics-core/src/main/cpp/CMakeLists.txt b/graphics/graphics-core/src/main/cpp/CMakeLists.txt
new file mode 100644
index 0000000..9ea81a9
--- /dev/null
+++ b/graphics/graphics-core/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,55 @@
+
+# For more information about using CMake with Android Studio, read the
+# documentation: https://d.android.com/studio/projects/add-native-code.html
+
+# Sets the minimum version of CMake required to build the native library.
+
+cmake_minimum_required(VERSION 3.18.1)
+
+# Declares and names the project.
+
+project("graphics-core")
+
+add_definitions(-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__)
+
+# Creates and names a library, sets it as either STATIC
+# or SHARED, and provides the relative paths to its source code.
+# You can define multiple libraries, and CMake builds them for you.
+# Gradle automatically packages shared libraries with your APK.
+
+add_library( # Sets the name of the library.
+             graphics-core
+
+             # Sets the library as a shared library.
+             SHARED
+
+             # Provides a relative path to your source file(s).
+             graphics-core.cpp
+             egl_utils.cpp)
+
+# Searches for a specified prebuilt library and stores the path as a
+# variable. Because CMake includes system libraries in the search path by
+# default, you only need to specify the name of the public NDK library
+# you want to add. CMake verifies that the library exists before
+# completing its build.
+
+find_library( # Sets the name of the path variable.
+              log-lib
+
+              # Specifies the name of the NDK library that
+              # you want CMake to locate.
+              log )
+
+# Specifies libraries CMake should link to your target library. You
+# can link multiple libraries, such as libraries you define in this
+# build script, prebuilt third-party libraries, or system libraries.
+
+target_link_libraries( # Specifies the target library.
+                       graphics-core
+
+                       # Links the target library to the log library
+                       # included in the NDK.
+                       ${log-lib}
+                       EGL
+                       GLESv2
+                       android)
diff --git a/graphics/graphics-core/src/main/cpp/egl_utils.cpp b/graphics/graphics-core/src/main/cpp/egl_utils.cpp
new file mode 100644
index 0000000..03cde33
--- /dev/null
+++ b/graphics/graphics-core/src/main/cpp/egl_utils.cpp
@@ -0,0 +1,346 @@
+/*
+ * Copyright 2022 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.
+ */
+#include <jni.h>
+#include <string>
+#include <poll.h>
+#include <unistd.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <android/log.h>
+#include <EGL/eglplatform.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <android/sync.h>
+#include <android/hardware_buffer_jni.h>
+#include <mutex>
+
+#define EGL_UTILS "EglUtils"
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, EGL_UTILS, __VA_ARGS__)
+
+/**
+ * Cached reference to the eglGetNativeClientBufferANDROID egl extension method
+ * On first invocation within the corresponding JNI method, a call to eglGetProcAddress
+ * is made to determine if this method exists. If it does then this function pointer
+ * is persisted for subsequent method calls.
+ */
+PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC eglGetNativeClientBufferANDROID = nullptr;
+
+/**
+ * Cached reference to the eglImageTargetTexture2DOES egl extension method.
+ * On first invocation within the corresponding JNI method, a call to eglGetProcAddress
+ * is made to determine if this method exists. If it does then this function pointer
+ * is persisted for subsequent method calls.
+ */
+PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = nullptr;
+
+/**
+ * Cached reference to the eglCreateImageKHR egl extension method.
+ * On first invocation within the corresponding JNI method, a call to eglGetProcAddress
+ * is made to determine if this method exists. If it does then this function pointer
+ * is persisted for subsequent method calls.
+ */
+PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = nullptr;
+
+/**
+ * Cached reference to the eglDestroyImageKHR egl extension method.
+ * On first invocation within the corresponding JNI method, a call to eglGetProcAddress
+ * is made to determine if this method exists. If it does then this function pointer
+ * is persisted for subsequent method calls.
+ */
+PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR = nullptr;
+
+/**
+ * Cached reference to the eglCreateSyncKHR egl extension method.
+ * On first invocation within the corresponding JNI method, a call to eglGetProcAddress
+ * is made to determine if this method exists. If it does then this function pointer
+ * is persisted for subsequent method calls.
+ */
+PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR = nullptr;
+
+/**
+ * Cached reference to the eglDestroySyncKHR egl extension method.
+ * On first invocation within the corresponding JNI method, a call to eglGetProcAddress
+ * is made to determine if this method exists. If it does then this function pointer
+ * is persisted for subsequent method calls.
+ */
+PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR = nullptr;
+
+/**
+ * Cached reference to the eglDupNativeFenceANDROID egl extension method.
+ * On first invocation within the corresponding JNI method, a call to eglGetProcAddress
+ * is made to determine if this method exists. If it does then this function pointer
+ * is persisted for subsequent method calls.
+ */
+PFNEGLDUPNATIVEFENCEFDANDROIDPROC eglDupNativeFenceANDROID = nullptr;
+
+/**
+ * Helper method for querying the EGL extension method eglGetNativeClientBufferANDROID.
+ * This is used in initial invocations of the corresponding JNI method to obtain
+ * an EGLClientBuffer instance from a HardwareBuffer as well as for testing purposes
+ * to guarantee that Android devices that advertise support for the corresponding
+ * extensions actually expose this API.
+ */
+static PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC obtainEglGetNativeClientBufferANDROID() {
+    return reinterpret_cast<PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC>(
+            eglGetProcAddress("eglGetNativeClientBufferANDROID"));
+}
+
+/**
+ * Helper method for querying the EGL extension method eglCreateImageKHR.
+ * This is used in initial invocations of the corresponding JNI method to obtain
+ * an EGLImage from an EGLClientBuffer as well as for testing purposes
+ * to guarantee that Android devices that advertise support for the corresponding
+ * extensions actually expose this API.
+ */
+static PFNEGLCREATEIMAGEKHRPROC obtainEglCreateImageKHR() {
+    return reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(
+            eglGetProcAddress("eglCreateImageKHR"));
+}
+
+/**
+ * Helper method for querying the EGL extension method eglDestroyImageKHR.
+ * This is used in initial invocations of the corresponding JNI method to destroy
+ * an EGLImage as well as for testing purposes to guarantee that Android devices
+ * that advertise support for the corresponding extensions actually expose this API.
+ */
+static PFNEGLDESTROYIMAGEKHRPROC obtainEglDestroyImageKHR() {
+    return reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(
+            eglGetProcAddress("eglDestroyImageKHR"));
+}
+
+/**
+ * Helper method for querying the EGL extension method glImageTargetTexture2DOES.
+ * This is used in initial invocations of the corresponding JNI method to load
+ * an EGLImage instance into a caller defined GL Texture as well as for testing
+ * purposes to guarantee that Android devices that advertise support for the
+ * corresponding extensions actually expose this API.
+ */
+static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC obtainGlImageTargetTexture2DOES() {
+    return reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(
+            eglGetProcAddress("glEGLImageTargetTexture2DOES"));
+}
+
+/**
+ * Helper method for querying the EGL extension method eglDupNativeFenceFDANDROID.
+ * This is used in initial invocations of the corresponding JNI method to to create EGL  fence sync
+ * objects that are associated with a native synchronization fence object that are referenced using
+ * a file descriptor. Additionally this is used for testing purposes to guarantee that Android
+ * devices that advertise support for the corresponding extensions actually expose this API.
+ */
+static PFNEGLDUPNATIVEFENCEFDANDROIDPROC obtainEglDupNativeFenceANDROID() {
+    return reinterpret_cast<PFNEGLDUPNATIVEFENCEFDANDROIDPROC>(
+            eglGetProcAddress("eglDupNativeFenceFDANDROID"));
+}
+
+/**
+ * Helper method for querying the EGL extension method eglCreateSyncKHR.
+ * This is used in initial invocations of the corresponding JNI method to to create EGL fence sync
+ * object. Additionally this is used for testing purposes to guarantee that Android
+ * devices that advertise support for the corresponding extensions actually expose this API.
+ */
+static PFNEGLCREATESYNCKHRPROC obtainEglCreateSyncKHR() {
+    return reinterpret_cast<PFNEGLCREATESYNCKHRPROC>(
+            eglGetProcAddress("eglCreateSyncKHR"));
+}
+
+/**
+ * Helper method for querying the EGL extension method eglDestroySyncKHR.
+ * This is used in initial invocations of the corresponding JNI method to destroy an EGL fence sync
+ * object. Additionally this is used for testing purposes to guarantee that Android devices that
+ * advertise support for corresponding extensions actually expose this API.
+ */
+static PFNEGLDESTROYSYNCKHRPROC obtainEglDestroySyncKHR() {
+    return reinterpret_cast<PFNEGLDESTROYSYNCKHRPROC>(
+            eglGetProcAddress("eglDestroySyncKHR"));
+}
+
+extern "C"
+JNIEXPORT jlong JNICALL
+Java_androidx_graphics_opengl_egl_EGLUtilsBindings_00024Companion_nCreateImageFromHardwareBuffer(
+        JNIEnv *env, jobject thiz, jlong egl_display_ptr, jobject hardware_buffer) {
+    static std::once_flag eglGetNativeClientBufferANDROIDFlag;
+    static std::once_flag eglCreateImageKHRFlag;
+    std::call_once(eglGetNativeClientBufferANDROIDFlag, [](){
+        eglGetNativeClientBufferANDROID = obtainEglGetNativeClientBufferANDROID();
+    });
+    if (!eglGetNativeClientBufferANDROID) {
+        ALOGE("Unable to resolve eglGetNativeClientBufferANDROID");
+        return 0;
+    }
+
+    std::call_once(eglCreateImageKHRFlag, [](){
+        eglCreateImageKHR = obtainEglCreateImageKHR();
+    });
+    if (!eglCreateImageKHR) {
+        ALOGE("Unable to resolve eglCreateImageKHR");
+        return 0;
+    }
+
+    AHardwareBuffer *buffer =
+            AHardwareBuffer_fromHardwareBuffer(env, hardware_buffer);
+    EGLClientBuffer eglClientBuffer = eglGetNativeClientBufferANDROID(buffer);
+
+    EGLint imageAttrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
+    auto display = reinterpret_cast<EGLDisplay *>(egl_display_ptr);
+    EGLImage image = eglCreateImageKHR(
+            display,
+            EGL_NO_CONTEXT,
+            EGL_NATIVE_BUFFER_ANDROID,
+            eglClientBuffer,
+            imageAttrs
+    );
+
+    return reinterpret_cast<jlong>(image);
+}
+
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_androidx_graphics_opengl_egl_EGLUtilsBindings_00024Companion_nDestroyImageKHR(
+        JNIEnv *env, jobject thiz, jlong egl_display_ptr, jlong egl_image_ptr) {
+    static std::once_flag eglDestroyImageKHRFlag;
+    std::call_once(eglDestroyImageKHRFlag, [](){
+        eglDestroyImageKHR = obtainEglDestroyImageKHR();
+    });
+    if (!eglDestroyImageKHR) {
+        ALOGE("Unable to resolve eglDestroyImageKHR");
+        return static_cast<jboolean>(false);
+    }
+
+    auto display = reinterpret_cast<EGLDisplay *>(egl_display_ptr);
+    auto eglImage = reinterpret_cast<EGLImage>(egl_image_ptr);
+    return static_cast<jboolean>(eglDestroyImageKHR(display, eglImage));
+}
+
+
+extern "C"
+JNIEXPORT void JNICALL
+Java_androidx_graphics_opengl_egl_EGLUtilsBindings_00024Companion_nImageTargetTexture2DOES(
+        JNIEnv *env, jobject thiz, jint target, jlong egl_image_ptr) {
+    static std::once_flag glEGLImageTargetTexture2DOESFlag;
+    std::call_once(glEGLImageTargetTexture2DOESFlag, [](){
+        glEGLImageTargetTexture2DOES = obtainGlImageTargetTexture2DOES();
+    });
+    if (!glEGLImageTargetTexture2DOES) {
+        ALOGE("Unable to resolve glEGLImageTargetTexture2DOES");
+        return;
+    }
+
+    glEGLImageTargetTexture2DOES(target, reinterpret_cast<EGLImage>(egl_image_ptr));
+}
+
+extern "C"
+JNIEXPORT jlong JNICALL
+Java_androidx_graphics_opengl_egl_EGLUtilsBindings_00024Companion_nCreateSyncKHR(
+        JNIEnv *env, jobject thiz, jlong egl_display_ptr, jint type,
+        jintArray attrs) {
+    static std::once_flag eglCreateSyncKHRFlag;
+    std::call_once(eglCreateSyncKHRFlag, [](){
+        eglCreateSyncKHR = obtainEglCreateSyncKHR();
+    });
+    if (!eglCreateSyncKHR) {
+        ALOGE("Unable to resolve eglCreateSyncKHR");
+        return 0;
+    }
+
+    auto display = reinterpret_cast<EGLDisplay *>(egl_display_ptr);
+    auto attrib_list = reinterpret_cast<EGLint *>(attrs);
+    return reinterpret_cast<jlong>(eglCreateSyncKHR(display, type, attrib_list));
+}
+
+
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_androidx_graphics_opengl_egl_EGLUtilsBindings_00024Companion_nDestroySyncKHR(
+        JNIEnv *env, jobject thiz, jlong egl_display_ptr, jlong sync_ptr) {
+    static std::once_flag eglDestroySyncKHRFlag;
+    std::call_once(eglDestroySyncKHRFlag, [](){
+        eglDestroySyncKHR = obtainEglDestroySyncKHR();
+    });
+    if (!eglDestroySyncKHR) {
+        ALOGE("Unable to resolve eglDestroySyncKHR");
+        return static_cast<jboolean>(false);
+    }
+
+    auto display = reinterpret_cast<EGLDisplay *>(egl_display_ptr);
+    auto sync = reinterpret_cast<EGLSync>(sync_ptr);
+    return static_cast<jboolean>(eglDestroySyncKHR(display, sync));
+}
+
+/**
+ * Helper method used in testing to verify if the eglGetNativeClientBufferANDROID method
+ * is actually supported on the Android device.
+ */
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_androidx_graphics_opengl_egl_EGLUtilsBindings_00024Companion_nSupportsEglGetNativeClientBufferAndroid(
+        JNIEnv *env, jobject thiz) {
+    return obtainEglGetNativeClientBufferANDROID() != nullptr;
+}
+
+/**
+ * Helper method used in testing to verify if the eglCreateImageKHR method
+ * is actually supported on the Android device.
+ */
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_androidx_graphics_opengl_egl_EGLUtilsBindings_00024Companion_nSupportsEglCreateImageKHR(
+        JNIEnv *env, jobject thiz) {
+    return obtainEglCreateImageKHR() != nullptr;
+}
+
+/**
+ * Helper method used in testing to verify if the eglDestroyImageKHR method
+ * is actually supported on the Android device.
+ */
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_androidx_graphics_opengl_egl_EGLUtilsBindings_00024Companion_nSupportsEglDestroyImageKHR(
+        JNIEnv *env, jobject thiz) {
+    return obtainEglDestroyImageKHR() != nullptr;
+}
+
+/**
+ * Helper method used in testing to verify if the glImageTargetTexture2DOES method
+ * is actually supported on the Android device.
+ */
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_androidx_graphics_opengl_egl_EGLUtilsBindings_00024Companion_nSupportsGlImageTargetTexture2DOES(
+        JNIEnv *env, jobject thiz) {
+    return obtainGlImageTargetTexture2DOES() != nullptr;
+}
+
+/**
+ * Helper method used in testing to verify if the eglCreateSyncKHR method is actually supported
+ * on the Android device
+ */
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_androidx_graphics_opengl_egl_EGLUtilsBindings_00024Companion_nSupportsEglCreateSyncKHR(
+        JNIEnv *env, jobject thiz) {
+    return obtainEglCreateSyncKHR() != nullptr;
+}
+
+/**
+ * Helper method used in testing to verify if the eglDestroySyncKHR method is actually supported
+ * on the Android device
+ */
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_androidx_graphics_opengl_egl_EGLUtilsBindings_00024Companion_nSupportsEglDestroySyncKHR(
+        JNIEnv *env, jobject thiz) {
+    return obtainEglDestroySyncKHR() != nullptr;
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/cpp/graphics-core.cpp b/graphics/graphics-core/src/main/cpp/graphics-core.cpp
new file mode 100644
index 0000000..f2489a8
--- /dev/null
+++ b/graphics/graphics-core/src/main/cpp/graphics-core.cpp
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ * 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.
+ */
+
+#define LOG_TAG "ASurfaceControlTest"
+
+#include <jni.h>
+#include <string>
+#include <poll.h>
+#include <unistd.h>
+#include <ctime>
+#include <android/native_activity.h>
+#include <android/surface_control.h>
+#include <android/api-level.h>
+#include <android/native_window_jni.h>
+#include <android/log.h>
+#include <android/sync.h>
+
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+
+extern "C"
+JNIEXPORT jlong JNICALL
+Java_androidx_graphics_surface_SurfaceControlCompat_nCreate(JNIEnv *env, jobject thiz,
+                                                            jlong surfaceControl,
+                                                            jstring debug_name) {
+    if (android_get_device_api_level() >= 29) {
+        auto aSurfaceControl = reinterpret_cast<ASurfaceControl *>(surfaceControl);
+        auto debugName = env->GetStringUTFChars(debug_name, nullptr);
+        return reinterpret_cast<jlong>(ASurfaceControl_create(aSurfaceControl,
+                                                              debugName));
+
+    } else {
+        return 0;
+    }
+}
+
+extern "C"
+JNIEXPORT jlong JNICALL
+Java_androidx_graphics_surface_SurfaceControlCompat_nCreateFromWindow(JNIEnv *env, jobject thiz,
+                                                                      jobject surface,
+                                                                      jstring debug_name) {
+    if (android_get_device_api_level() >= 29) {
+        auto AWindow = ANativeWindow_fromSurface(env, surface);
+        auto debugName = env->GetStringUTFChars(debug_name, nullptr);
+        auto surfaceControl = reinterpret_cast<jlong>(ASurfaceControl_createFromWindow(AWindow,
+                                                                                       debugName));
+
+        ANativeWindow_release(AWindow);
+        return surfaceControl;
+    } else {
+        return 0;
+    }
+}
+
+extern "C"
+JNIEXPORT void JNICALL
+Java_androidx_graphics_surface_SurfaceControlCompat_nRelease(JNIEnv *env, jobject thiz,
+                                                             jlong surfaceControl) {
+    if (android_get_device_api_level() >= 29) {
+        ASurfaceControl_release(reinterpret_cast<ASurfaceControl *>(surfaceControl));
+    } else {
+        return;
+    }
+}
+
+extern "C"
+JNIEXPORT jlong JNICALL
+Java_androidx_graphics_surface_SurfaceControlCompat_00024Transaction_nTransactionCreate(
+        JNIEnv *env, jobject thiz) {
+    if (android_get_device_api_level() >= 29) {
+        return reinterpret_cast<jlong>(ASurfaceTransaction_create());
+    } else {
+        return 0;
+    }
+}
+
+extern "C"
+JNIEXPORT void JNICALL
+Java_androidx_graphics_surface_SurfaceControlCompat_00024Transaction_nTransactionDelete(
+        JNIEnv *env, jobject thiz,
+        jlong surfaceTransaction) {
+    if (android_get_device_api_level() >= 29) {
+        ASurfaceTransaction_delete(reinterpret_cast<ASurfaceTransaction *>(surfaceTransaction));
+    }
+}
+
+extern "C"
+JNIEXPORT void JNICALL
+Java_androidx_graphics_surface_SurfaceControlCompat_00024Transaction_nTransactionApply(
+        JNIEnv *env, jobject thiz,
+        jlong surfaceTransaction) {
+    if (android_get_device_api_level() >= 29) {
+        ASurfaceTransaction_apply(reinterpret_cast<ASurfaceTransaction *>(surfaceTransaction));
+    }
+}
+
+static struct {
+    jclass clazz;
+    jmethodID onComplete;
+} gTransactionCompletedListenerClassInfo;
+
+#define NANO_SECONDS 1000000000LL
+
+int64_t getSystemTime() {
+    struct timespec time;
+    int result = clock_gettime(CLOCK_MONOTONIC, &time);
+    if (result < 0) {
+        return -errno;
+    }
+    return (time.tv_sec * NANO_SECONDS) + time.tv_nsec;
+}
+
+/**
+ * This wrapper class mimics the one found in CTS tests, specifcally
+ * android_view_cts_ASurfaceControlTest.cpp and serves
+ * to allow us to set a callback for Transaction onComplete.
+ */
+class CallbackWrapper {
+public:
+    explicit CallbackWrapper(JNIEnv *env, jobject object) {
+        env->GetJavaVM(&mVm);
+        mCallbackObject = env->NewGlobalRef(object);
+    }
+
+    ~CallbackWrapper() {
+        getEnv()->DeleteGlobalRef(mCallbackObject);
+    }
+
+    void callback(ASurfaceTransactionStats *stats) {
+        JNIEnv *env = getEnv();
+        int64_t latchTime = ASurfaceTransactionStats_getLatchTime(stats);
+        uint64_t presentTime = getSystemTime();
+
+        env->CallVoidMethod(mCallbackObject,
+                            gTransactionCompletedListenerClassInfo.onComplete, latchTime,
+                            presentTime);
+    }
+
+    static void transactionCallbackThunk(void *context, ASurfaceTransactionStats *stats) {
+        CallbackWrapper *listener = reinterpret_cast<CallbackWrapper *>(context);
+        listener->callback(stats);
+        delete listener;
+    }
+
+private:
+    JavaVM *mVm;
+    jobject mCallbackObject;
+
+    JNIEnv *getEnv() {
+        JNIEnv *env;
+        mVm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
+        return env;
+    }
+};
+
+void setupTransactionCompletedListenerClassInfo(JNIEnv *env) {
+    //setup transactionCompleteListenerClassInfo for test usage
+    jclass transactionCompletedListenerClazz =
+            env->FindClass(
+                    "androidx/graphics/surface/SurfaceControlCompat$TransactionCompletedListener");
+    gTransactionCompletedListenerClassInfo.clazz =
+            static_cast<jclass>(env->NewGlobalRef(transactionCompletedListenerClazz));
+    gTransactionCompletedListenerClassInfo.onComplete =
+            env->GetMethodID(transactionCompletedListenerClazz, "onComplete",
+                             "(JJ)V");
+}
+
+extern "C"
+JNIEXPORT void JNICALL
+Java_androidx_graphics_surface_SurfaceControlCompat_00024Transaction_nTransactionSetOnComplete(
+        JNIEnv *env,
+        jobject thiz,
+        jlong surfaceTransaction, jobject callback) {
+    if (android_get_device_api_level() >= 29) {
+        setupTransactionCompletedListenerClassInfo(env);
+        void *context = new CallbackWrapper(env, callback);
+        ASurfaceTransaction_setOnComplete(
+                reinterpret_cast<ASurfaceTransaction *>(surfaceTransaction),
+                reinterpret_cast<void *>(context),
+                CallbackWrapper::transactionCallbackThunk);
+    }
+}
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/GLRenderer.kt b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/GLRenderer.kt
new file mode 100644
index 0000000..f150a79
--- /dev/null
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/GLRenderer.kt
@@ -0,0 +1,681 @@
+/*
+ * Copyright 2022 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.graphics.opengl
+
+import android.graphics.SurfaceTexture
+import android.opengl.EGL14
+import android.opengl.EGLConfig
+import android.opengl.EGLSurface
+import android.view.Surface
+import android.view.SurfaceHolder
+import android.view.SurfaceView
+import android.view.TextureView
+import androidx.annotation.WorkerThread
+import androidx.graphics.opengl.egl.EglConfigAttributes8888
+import androidx.graphics.opengl.egl.EglManager
+import androidx.graphics.opengl.egl.EglSpec
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.atomic.AtomicInteger
+
+/**
+ * Class responsible for coordination of requests to render into surfaces using OpenGL.
+ * This creates a backing thread to handle EGL dependencies and draw leveraging OpenGL across
+ * multiple [android.view.Surface] instances that can be attached and detached throughout
+ * the lifecycle of an application. Usage of this class is recommended to be done on the UI thread.
+ *
+ * @param eglSpecFactory Callback invoked to determine the EGL spec version to use
+ * for EGL management. This is invoked on the GL Thread
+ * @param eglConfigFactory Callback invoked to determine the appropriate EGLConfig used
+ * to create the EGL context. This is invoked on the GL Thread
+ */
+// GL is the industry standard for referencing OpenGL vs Gl (lowercase l)
+@Suppress("AcronymName")
+class GLRenderer(
+    eglSpecFactory: () -> EglSpec = { EglSpec.Egl14 },
+    eglConfigFactory: EglManager.() -> EGLConfig = {
+        // 8 bit channels should always be supported
+        loadConfig(EglConfigAttributes8888)
+            ?: throw IllegalStateException("Unable to obtain config for 8 bit EGL " +
+                "configuration")
+    }
+) {
+
+    /**
+     * Factory method to determine which EglSpec the underlying EglManager implementation uses
+     */
+    private val mEglSpecFactory: () -> EglSpec = eglSpecFactory
+
+    /**
+     * Factory method used to create the corresponding EGLConfig used to create the EGLRenderer used
+     * by EglManager
+     */
+    private val mEglConfigFactory: EglManager.() -> EGLConfig = eglConfigFactory
+
+    /**
+     * GLThread used to manage EGL dependencies, create EGLSurfaces and draw content
+     */
+    private var mGLThread: GLThread? = null
+
+    /**
+     * Collection of [RenderTarget] instances that are managed by the GLRenderer
+     */
+    private val mRenderTargets = ArrayList<RenderTarget>()
+
+    /**
+     * Collection of callbacks to be invoked when the EGL dependencies are initialized
+     * or torn down
+     */
+    private val mEglContextCallback = HashSet<EglContextCallback>()
+
+    /**
+     * Removes the corresponding [RenderTarget] from management of the GLThread.
+     * This destroys the EGLSurface associated with this surface and subsequent requests
+     * to render into the surface with the provided token are ignored.
+     *
+     * If the [cancelPending] flag is set to true, any queued request
+     * to render that has not started yet is cancelled. However, if this is invoked in the
+     * middle of the frame being rendered, it will continue to process the current frame.
+     *
+     * Additionally if this flag is false, all pending requests to render will be processed
+     * before the [RenderTarget] is detached.
+     *
+     * Note the detach operation will only occur if the GLRenderer is started, that is if
+     * [isRunning] returns true. Otherwise this is a no-op. GLRenderer will automatically detach all
+     * [RenderTarget] instances as part of its teardown process.
+     */
+    @JvmOverloads
+    fun detach(
+        target: RenderTarget,
+        cancelPending: Boolean,
+        @WorkerThread onDetachComplete: ((RenderTarget) -> Unit)? = null
+    ) {
+        if (mRenderTargets.contains(target)) {
+            mGLThread?.detachSurface(target.token, cancelPending) {
+                // WorkerThread
+                target.release()
+                target.onDetach.invoke()
+                onDetachComplete?.invoke(target)
+            }
+            mRenderTargets.remove(target)
+        }
+    }
+
+    /**
+     * Determines if the GLThread has been started. That is [start] has been invoked
+     * on this GLRenderer instance without a corresponding call to [stop].
+     */
+    fun isRunning(): Boolean = mGLThread != null
+
+    /**
+     * Starts the GLThread. After this method is called, consumers can attempt
+     * to attach [android.view.Surface] instances through [attach] as well as
+     * schedule content to be drawn through [requestRender]
+     *
+     * @param name Optional name to provide to the GLThread
+     *
+     * @throws IllegalStateException if EGLConfig with desired attributes cannot be created
+     */
+    @JvmOverloads
+    fun start(
+        name: String = "GLThread",
+    ) {
+        if (mGLThread == null) {
+            GLThread.log("starting thread...")
+            mGLThread = GLThread(
+                name,
+                mEglSpecFactory,
+                mEglConfigFactory
+            ).apply {
+                start()
+                if (!mEglContextCallback.isEmpty()) {
+                    // Add a copy of the current collection as new entries to mEglContextCallback
+                    // could be mistakenly added multiple times.
+                    this.addEglCallbacks(ArrayList<EglContextCallback>(mEglContextCallback))
+                }
+            }
+        }
+    }
+
+    /**
+     * Mark the corresponding surface session with the given token as dirty
+     * to schedule a call to [RenderCallback#onDrawFrame].
+     * If there is already a queued request to render into the provided surface with
+     * the specified token, this request is ignored.
+     *
+     * Note the render operation will only occur if the GLRenderer is started, that is if
+     * [isRunning] returns true. Otherwise this is a no-op.
+     *
+     * @param target RenderTarget to be re-rendered
+     * @param onRenderComplete Optional callback invoked on the backing thread after the frame has
+     * been rendered.
+     */
+    @JvmOverloads
+    fun requestRender(target: RenderTarget, onRenderComplete: ((RenderTarget) -> Unit)? = null) {
+        val token = target.token
+        val callbackRunnable = if (onRenderComplete != null) {
+            Runnable {
+                onRenderComplete.invoke(target)
+            }
+        } else {
+            null
+        }
+        mGLThread?.requestRender(token, callbackRunnable)
+    }
+
+    /**
+     * Resize the corresponding surface associated with the RenderTarget to the specified
+     * width and height and re-render. This will destroy the EGLSurface created by
+     * [RenderCallback.onSurfaceCreated] and invoke it again with the updated dimensions.
+     * An optional callback is invoked on the backing thread after the resize operation
+     * is complete.
+     *
+     * Note the resize operation will only occur if the GLRenderer is started, that is if
+     * [isRunning] returns true. Otherwise this is a no-op.
+     *
+     * @param target RenderTarget to be resized
+     * @param width Updated width of the corresponding surface
+     * @param height Updated height of the corresponding surface
+     * @param onResizeComplete Optional callback invoked on the backing thread when the resize
+     * operation is complete
+     */
+    @JvmOverloads
+    fun resize(
+        target: RenderTarget,
+        width: Int,
+        height: Int,
+        onResizeComplete: ((RenderTarget) -> Unit)? = null
+    ) {
+        val token = target.token
+        val callbackRunnable = if (onResizeComplete != null) {
+            Runnable {
+                onResizeComplete.invoke(target)
+            }
+        } else {
+            null
+        }
+        mGLThread?.resizeSurface(token, width, height, callbackRunnable)
+    }
+
+    /**
+     * Stop the corresponding GL thread. This destroys all EGLSurfaces as well
+     * as any other EGL dependencies. All queued requests that have not been processed
+     * yet are cancelled.
+     *
+     * Note the stop operation will only occur if the GLRenderer was previously started, that is
+     * [isRunning] returns true. Otherwise this is a no-op.
+     *
+     * @param cancelPending If true all pending requests and cancelled and the backing thread is
+     * torn down immediately. If false, all pending requests are processed first before tearing
+     * down the backing thread. Subsequent requests made after this call are ignored.
+     * @param onStop Optional callback invoked on the backing thread after it is torn down.
+     */
+    @JvmOverloads
+    fun stop(cancelPending: Boolean, onStop: ((GLRenderer) -> Unit)? = null) {
+        GLThread.log("stopping thread...")
+        // Make a copy of the render targets to call cleanup operations on to avoid potential
+        // concurrency issues.
+        // This method will clear the existing collection and we do not want to potentially tear
+        // down a target that was attached after a subsequent call to start if the tear down
+        // callback execution is delayed if previously pending requests have not been cancelled
+        // (i.e. cancelPending is false)
+        val renderTargets = ArrayList(mRenderTargets)
+        mGLThread?.tearDown(cancelPending) {
+            // No need to call target.detach as this callback is invoked after
+            // the dependencies are cleaned up
+            for (target in renderTargets) {
+                target.release()
+                target.onDetach.invoke()
+            }
+            onStop?.invoke(this@GLRenderer)
+        }
+        mGLThread = null
+        mRenderTargets.clear()
+    }
+
+    /**
+     * Add an [EglContextCallback] to receive callbacks for construction and
+     * destruction of EGL dependencies.
+     *
+     * These callbacks are invoked on the backing thread.
+     */
+    fun registerEglContextCallback(callback: EglContextCallback) {
+        mEglContextCallback.add(callback)
+        mGLThread?.addEglCallback(callback)
+    }
+
+    /**
+     * Remove [EglContextCallback] to no longer receive callbacks for construction and
+     * destruction of EGL dependencies.
+     *
+     * These callbacks are invoked on the backing thread
+     */
+    fun unregisterEglContextCallback(callback: EglContextCallback) {
+        mEglContextCallback.remove(callback)
+        mGLThread?.removeEglCallback(callback)
+    }
+
+    /**
+     * Callbacks invoked when the GL dependencies are created and destroyed.
+     * These are logical places to setup and tear down any dependencies that are used
+     * for drawing content within a frame (ex. compiling shaders)
+     */
+    interface EglContextCallback {
+
+        /**
+         * Callback invoked on the backing thread after EGL dependencies are initialized.
+         * This is guaranteed to be invoked before any instance of
+         * [RenderCallback.onSurfaceCreated] is called.
+         * This will be invoked lazily before the first request to [GLRenderer.requestRender]
+         */
+        @WorkerThread
+        fun onEglContextCreated(eglManager: EglManager)
+
+        /**
+         * Callback invoked on the backing thread before EGL dependencies are about to be torn down.
+         * This is invoked after [GLRenderer.stop] is processed.
+         */
+        @WorkerThread
+        fun onEglContextDestroyed(eglManager: EglManager)
+    }
+
+    /**
+     * Interface used for creating an [EGLSurface] with a user defined configuration
+     * from the provided surface as well as a callback used to render content into the surface
+     * for a given frame
+     */
+    interface RenderCallback {
+        /**
+         * Used to create a corresponding [EGLSurface] from the provided
+         * [android.view.Surface] instance. This enables consumers to configure
+         * the corresponding [EGLSurface] they wish to render into.
+         * The [EGLSurface] created here is guaranteed to be the current surface
+         * before [onDrawFrame] is called. That is, implementations of onDrawFrame
+         * do not need to call eglMakeCurrent on this [EGLSurface].
+         *
+         * This method is invoked on the GL thread.
+         *
+         * The default implementation will create a window surface with EGL_WIDTH and EGL_HEIGHT
+         * set to [width] and [height] respectively.
+         * Implementations can override this method to provide additional EglConfigAttributes
+         * for this surface (ex. [EGL14.EGL_SINGLE_BUFFER]
+         *
+         * @param spec EGLSpec used to create the corresponding EGLSurface
+         * @param config EGLConfig used to create the corresponding EGLSurface
+         * @param surface [android.view.Surface] used to create an EGLSurface from
+         * @param width Desired width of the surface to create
+         * @param height Desired height of the surface to create
+         */
+        @WorkerThread
+        fun onSurfaceCreated(
+            spec: EglSpec,
+            config: EGLConfig,
+            surface: Surface,
+            width: Int,
+            height: Int
+        ): EGLSurface =
+            // Always default to creating an EGL window surface
+            // Despite having access to the width and height here, do not explicitly
+            // pass in EGLConfigAttributes specifying the EGL_WIDTH and EGL_HEIGHT parameters
+            // as those are not accepted parameters for eglCreateWindowSurface but they are
+            // for other EGL Surface factory methods such as eglCreatePBufferSurface
+            // See accepted parameters here:
+            // https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglCreateWindowSurface.xhtml
+            // and here
+            // https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglCreatePbufferSurface.xhtml
+            spec.eglCreateWindowSurface(config, surface, null)
+
+        /**
+         * Callback used to issue OpenGL drawing commands into the [EGLSurface]
+         * created in [onSurfaceCreated]. This [EGLSurface] is guaranteed to
+         * be current before this callback is invoked and [EglManager.swapAndFlushBuffers]
+         * will be invoked afterwards. If additional scratch [EGLSurface]s are used
+         * here it is up to the implementation of this method to ensure that the proper
+         * surfaces are made current and the appropriate swap buffers call is made
+         *
+         * This method is invoked on the backing thread
+         *
+         * @param eglManager Handle to EGL dependencies
+         */
+        @WorkerThread
+        fun onDrawFrame(eglManager: EglManager)
+    }
+
+    /**
+     * Adds the [android.view.Surface] to be managed by the GLThread.
+     * A corresponding [EGLSurface] is created on the GLThread as well as a callback
+     * for rendering into the surface through [RenderCallback].
+     * Unlike the other [attach] methods that consume a [SurfaceView] or [TextureView],
+     * this method does not handle any lifecycle callbacks associated with the target surface.
+     * Therefore it is up to the consumer to properly setup/teardown resources associated with
+     * this surface.
+     *
+     * @param surface Target surface to be managed by the backing thread
+     * @param width Desired width of the [surface]
+     * @param height Desired height of the [surface]
+     * @param renderer Callbacks used to create a corresponding [EGLSurface] from the
+     * given surface as well as render content into the created [EGLSurface]
+     * @return [RenderTarget] used for subsequent requests to communicate
+     * with the provided Surface (ex. [requestRender] or [detach]).
+     *
+     * @throws IllegalStateException If this method was called when the GLThread has not started
+     * (i.e. start has not been called)
+     */
+    fun attach(surface: Surface, width: Int, height: Int, renderer: RenderCallback): RenderTarget {
+        val thread = mGLThread
+        if (thread != null) {
+            val token = sToken.getAndIncrement()
+            thread.attachSurface(token, surface, width, height, renderer)
+            return RenderTarget(token, this).also { mRenderTargets.add(it) }
+        } else {
+            throw IllegalStateException("GLThread not started, did you forget to call start?")
+        }
+    }
+
+    /**
+     * Adds the [android.view.Surface] provided by the given [SurfaceView] to be managed by the
+     * backing thread.
+     *
+     * A corresponding [EGLSurface] is created on the GLThread as well as a callback
+     * for rendering into the surface through [RenderCallback].
+     *
+     * This method automatically configures a [SurfaceHolder.Callback] used to attach the
+     * [android.view.Surface] when the underlying [SurfaceHolder] that contains the surface is
+     * available. Similarly this surface will be detached from [GLRenderer] when the surface provided
+     * by the [SurfaceView] is destroyed (i.e. [SurfaceHolder.Callback.surfaceDestroyed] is called.
+     *
+     * If the [android.view.Surface] is already available by the time this method is invoked,
+     * it is attached synchronously.
+     *
+     * @param surfaceView SurfaceView that provides the surface to be rendered by the backing thread
+     * @param renderer callbacks used to create a corresponding [EGLSurface] from the
+     * given surface as well as render content into the created [EGLSurface]
+     * @return [RenderTarget] used for subsequent requests to communicate
+     * with the provided Surface (ex. [requestRender] or [detach]).
+     *
+     * @throws IllegalStateException If this method was called when the GLThread has not started
+     * (i.e. start has not been called)
+     */
+    fun attach(surfaceView: SurfaceView, renderer: RenderCallback): RenderTarget {
+        val thread = mGLThread
+        if (thread != null) {
+            val token = sToken.getAndIncrement()
+            val holder = surfaceView.holder
+            val callback = object : SurfaceHolder.Callback2 {
+
+                var isAttached = false
+
+                /**
+                 * Optional condition that maybe used if we are issuing a blocking call to render
+                 * in [SurfaceHolder.Callback2.surfaceRedrawNeeded]
+                 * In this case we need to signal the condition of either the request to render
+                 * has completed, or if the RenderTarget has been detached and the pending
+                 * render request is cancelled.
+                 */
+                @Volatile var renderLatch: CountDownLatch? = null
+
+                val renderTarget = RenderTarget(token, this@GLRenderer) @WorkerThread {
+                    isAttached = false
+                    // SurfaceHolder.add/remove callback is thread safe
+                    holder.removeCallback(this)
+                    // Countdown in case we have been detached while waiting for a render
+                    // to be completed
+                    renderLatch?.countDown()
+                }
+
+                override fun surfaceRedrawNeeded(p0: SurfaceHolder) {
+                    val latch = CountDownLatch(1).also { renderLatch = it }
+                    // Request a render and block until the rendering is complete
+                    // surfaceRedrawNeeded is invoked on older API levels and is replaced with
+                    // surfaceRedrawNeededAsync for newer API levels which is non-blocking
+                    renderTarget.requestRender @WorkerThread {
+                        latch.countDown()
+                    }
+                    latch.await()
+                    renderLatch = null
+                }
+
+                override fun surfaceRedrawNeededAsync(
+                    holder: SurfaceHolder,
+                    drawingFinished: Runnable
+                ) {
+                    renderTarget.requestRender {
+                        drawingFinished.run()
+                    }
+                }
+
+                override fun surfaceCreated(holder: SurfaceHolder) {
+                    // NO-OP wait until surfaceChanged which is guaranteed to be called and also
+                    // provides the appropriate width height of the surface
+                }
+
+                override fun surfaceChanged(
+                    holder: SurfaceHolder,
+                    format: Int,
+                    width: Int,
+                    height: Int
+                ) {
+                    if (!isAttached) {
+                        thread.attachSurface(token, holder.surface, width, height, renderer)
+                        isAttached = true
+                    } else {
+                        renderTarget.resize(width, height)
+                    }
+                    renderTarget.requestRender()
+                }
+
+                override fun surfaceDestroyed(holder: SurfaceHolder) {
+                    val detachLatch = CountDownLatch(1)
+                    renderTarget.detach(true) {
+                        detachLatch.countDown()
+                    }
+                    detachLatch.await()
+                }
+            }
+            holder.addCallback(callback)
+            if (holder.surface != null && holder.surface.isValid) {
+                thread.attachSurface(
+                    token,
+                    holder.surface,
+                    surfaceView.width,
+                    surfaceView.height,
+                    renderer
+                )
+            }
+            mRenderTargets.add(callback.renderTarget)
+            return callback.renderTarget
+        } else {
+            throw IllegalStateException("GLThread not started, did you forget to call start?")
+        }
+    }
+
+    /**
+     * Adds the [android.view.Surface] provided by the given [TextureView] to be managed by the
+     * backing thread.
+     *
+     * A corresponding [EGLSurface] is created on the GLThread as well as a callback
+     * for rendering into the surface through [RenderCallback].
+     *
+     * This method automatically configures a [TextureView.SurfaceTextureListener] used to create a
+     * [android.view.Surface] when the underlying [SurfaceTexture] is available.
+     * Similarly this surface will be detached from [GLRenderer] if the underlying [SurfaceTexture]
+     * is destroyed (i.e. [TextureView.SurfaceTextureListener.onSurfaceTextureDestroyed] is called.
+     *
+     * If the [SurfaceTexture] is already available by the time this method is called, then it is
+     * attached synchronously.
+     *
+     * @param textureView TextureView that provides the surface to be rendered into on the GLThread
+     * @param renderer callbacks used to create a corresponding [EGLSurface] from the
+     * given surface as well as render content into the created [EGLSurface]
+     * @return [RenderTarget] used for subsequent requests to communicate
+     * with the provided Surface (ex. [requestRender] or [detach]).
+     *
+     * @throws IllegalStateException If this method was called when the GLThread has not started
+     * (i.e. start has not been called)
+     */
+    fun attach(textureView: TextureView, renderer: RenderCallback): RenderTarget {
+        val thread = mGLThread
+        if (thread != null) {
+            val token = sToken.getAndIncrement()
+            val renderTarget = RenderTarget(token, this) @WorkerThread {
+                textureView.handler?.post {
+                    textureView.surfaceTextureListener = null
+                }
+            }
+            textureView.surfaceTextureListener = object : TextureView.SurfaceTextureListener {
+                override fun onSurfaceTextureAvailable(
+                    surfaceTexture: SurfaceTexture,
+                    width: Int,
+                    height: Int
+                ) {
+                    thread.attachSurface(token, Surface(surfaceTexture), width, height, renderer)
+                }
+
+                override fun onSurfaceTextureSizeChanged(
+                    texture: SurfaceTexture,
+                    width: Int,
+                    height: Int
+                ) {
+                    renderTarget.resize(width, height)
+                    renderTarget.requestRender()
+                }
+
+                override fun onSurfaceTextureDestroyed(p0: SurfaceTexture): Boolean {
+                    val detachLatch = CountDownLatch(1)
+                    renderTarget.detach(true) {
+                        detachLatch.countDown()
+                    }
+                    detachLatch.await()
+                    return true
+                }
+
+                override fun onSurfaceTextureUpdated(p0: SurfaceTexture) {
+                    // NO-OP
+                }
+            }
+            if (textureView.isAvailable) {
+                thread.attachSurface(
+                    token,
+                    Surface(textureView.surfaceTexture),
+                    textureView.width,
+                    textureView.height,
+                    renderer
+                )
+            }
+            mRenderTargets.add(renderTarget)
+            return renderTarget
+        } else {
+            throw IllegalStateException("GLThread not started, did you forget to call start?")
+        }
+    }
+
+    /**
+     * Handle to a [android.view.Surface] that is given to [GLRenderer] to handle
+     * rendering.
+     */
+    class RenderTarget internal constructor(
+        internal val token: Int,
+        glManager: GLRenderer,
+        @WorkerThread internal val onDetach: () -> Unit = {}
+    ) {
+
+        @Volatile
+        private var mManager: GLRenderer? = glManager
+
+        internal fun release() {
+            mManager = null
+        }
+
+        /**
+         * Request that this [RenderTarget] should have its contents redrawn.
+         * This consumes an optional callback that is invoked on the backing thread when
+         * the rendering is completed.
+         *
+         * Note the render operation will only occur if the RenderTarget is attached, that is
+         * [isAttached] returns true. If the [RenderTarget] is detached or the [GLRenderer] that
+         * created this RenderTarget is stopped, this is a no-op.
+         *
+         * @param onRenderComplete Optional callback called on the backing thread when
+         * rendering is finished
+         */
+        @JvmOverloads
+        fun requestRender(@WorkerThread onRenderComplete: ((RenderTarget) -> Unit)? = null) {
+            mManager?.requestRender(this@RenderTarget, onRenderComplete)
+        }
+
+        /**
+         * Determines if the current RenderTarget is attached to GLRenderer.
+         * This is true until [detach] has been called. If the RenderTarget is no longer
+         * in an attached state (i.e. this returns false). Subsequent calls to [requestRender]
+         * will be ignored.
+         */
+        fun isAttached(): Boolean = mManager != null
+
+        /**
+         * Resize the RenderTarget to the specified width and height.
+         * This will destroy the EGLSurface created by [RenderCallback.onSurfaceCreated]
+         * and invoke it again with the updated dimensions.
+         * An optional callback is invoked on the backing thread after the resize operation
+         * is complete
+         *
+         * Note the resize operation will only occur if the RenderTarget is attached, that is
+         * [isAttached] returns true. If the [RenderTarget] is detached or the [GLRenderer] that
+         * created this RenderTarget is stopped, this is a no-op.
+         *
+         * @param width New target width to resize the RenderTarget
+         * @param height New target height to resize the RenderTarget
+         * @param onResizeComplete Optional callback invoked after the resize is complete
+         */
+        @JvmOverloads
+        fun resize(
+            width: Int,
+            height: Int,
+            @WorkerThread onResizeComplete: ((RenderTarget) -> Unit)? = null
+        ) {
+            mManager?.resize(this, width, height, onResizeComplete)
+        }
+
+        /**
+         * Removes the corresponding [RenderTarget] from management of the GLThread.
+         * This destroys the EGLSurface associated with this surface and subsequent requests
+         * to render into the surface with the provided token are ignored.
+         *
+         * If the [cancelPending] flag is set to true, any queued request
+         * to render that has not started yet is cancelled. However, if this is invoked in the
+         * middle of the frame being rendered, it will continue to process the current frame.
+         *
+         * Additionally if this flag is false, all pending requests to render will be processed
+         * before the [RenderTarget] is detached.
+         *
+         * This is a convenience method around [GLRenderer.detach]
+         *
+         * Note the detach operation will only occur if the RenderTarget is attached, that is
+         * [isAttached] returns true. If the [RenderTarget] is detached or the [GLRenderer] that
+         * created this RenderTarget is stopped, this is a no-op.
+         */
+        @JvmOverloads
+        fun detach(cancelPending: Boolean, onDetachComplete: ((RenderTarget) -> Unit)? = null) {
+            mManager?.detach(this, cancelPending, onDetachComplete)
+        }
+    }
+
+    companion object {
+        /**
+         * Counter used to issue unique identifiers for surfaces that are managed by GLRenderer
+         */
+        private val sToken = AtomicInteger()
+    }
+}
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/GLThread.kt b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/GLThread.kt
new file mode 100644
index 0000000..368ecf0
--- /dev/null
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/GLThread.kt
@@ -0,0 +1,384 @@
+/*
+ * Copyright 2022 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.graphics.opengl
+
+import android.opengl.EGL14
+import android.opengl.EGLConfig
+import android.opengl.EGLSurface
+import android.os.Handler
+import android.os.HandlerThread
+import android.os.SystemClock
+import android.util.Log
+import android.view.Surface
+import androidx.annotation.AnyThread
+import androidx.annotation.WorkerThread
+import androidx.graphics.opengl.GLRenderer.EglContextCallback
+import androidx.graphics.opengl.GLRenderer.RenderCallback
+import androidx.graphics.opengl.egl.EglManager
+import androidx.graphics.opengl.egl.EglSpec
+import java.util.concurrent.atomic.AtomicBoolean
+
+/**
+ * Thread responsible for management of EGL dependencies, setup and teardown
+ * of EGLSurface instances as well as delivering callbacks to draw a frame
+ */
+internal class GLThread(
+    name: String = "GLThread",
+    private val mEglSpecFactory: () -> EglSpec,
+    private val mEglConfigFactory: EglManager.() -> EGLConfig,
+) : HandlerThread(name) {
+
+    // Accessed on internal HandlerThread
+    private val mIsTearingDown = AtomicBoolean(false)
+    private var mEglManager: EglManager? = null
+    private val mSurfaceSessions = HashMap<Int, SurfaceSession>()
+    private var mHandler: Handler? = null
+    private val mEglContextCallback = HashSet<EglContextCallback>()
+
+    override fun start() {
+        super.start()
+        mHandler = Handler(looper)
+    }
+
+    /**
+     * Adds the given [android.view.Surface] to be managed by the GLThread.
+     * A corresponding [EGLSurface] is created on the GLThread as well as a callback
+     * for rendering into the surface through [RenderCallback].
+     * @param surface intended to be be rendered into on the GLThread
+     * @param width Desired width of the [surface]
+     * @param height Desired height of the [surface]
+     * @param renderer callbacks used to create a corresponding [EGLSurface] from the
+     * given surface as well as render content into the created [EGLSurface]
+     * @return Identifier used for subsequent requests to communicate
+     * with the provided Surface (ex. [requestRender] or [detachSurface]
+     */
+    @AnyThread
+    fun attachSurface(
+        token: Int,
+        surface: Surface,
+        width: Int,
+        height: Int,
+        renderer: RenderCallback
+    ) {
+        withHandler {
+            post(token) {
+                attachSurfaceSessionInternal(
+                    SurfaceSession(token, surface, renderer).apply {
+                        this.width = width
+                        this.height = height
+                    }
+                )
+            }
+        }
+    }
+
+    @AnyThread
+    fun resizeSurface(token: Int, width: Int, height: Int, callback: Runnable? = null) {
+        withHandler {
+            post(token) {
+                resizeSurfaceSessionInternal(token, width, height)
+                requestRenderInternal(token)
+                callback?.run()
+            }
+        }
+    }
+
+    @AnyThread
+    fun addEglCallbacks(callbacks: ArrayList<EglContextCallback>) {
+        withHandler {
+            post {
+                mEglContextCallback.addAll(callbacks)
+                mEglManager?.let {
+                    for (callback in callbacks) {
+                        callback.onEglContextCreated(it)
+                    }
+                }
+            }
+        }
+    }
+
+    @AnyThread
+    fun addEglCallback(callbacks: EglContextCallback) {
+        withHandler {
+            post {
+                mEglContextCallback.add(callbacks)
+                // If EGL dependencies are already initialized, immediately invoke
+                // the added callback
+                mEglManager?.let {
+                    callbacks.onEglContextCreated(it)
+                }
+            }
+        }
+    }
+
+    @AnyThread
+    fun removeEglCallback(callbacks: EglContextCallback) {
+        withHandler {
+            post {
+                mEglContextCallback.remove(callbacks)
+            }
+        }
+    }
+
+    /**
+     * Removes the corresponding [android.view.Surface] from management of the GLThread.
+     * This destroys the EGLSurface associated with this surface and subsequent requests
+     * to render into the surface with the provided token are ignored. Any queued request
+     * to render to the corresponding [SurfaceSession] that has not started yet is cancelled.
+     * However, if this is invoked in the middle of the frame being rendered, it will continue to
+     * process the current frame.
+     */
+    @AnyThread
+    fun detachSurface(
+        token: Int,
+        cancelPending: Boolean,
+        callback: Runnable?
+    ) {
+        log("dispatching request to detach surface w/ token: $token")
+        withHandler {
+            if (cancelPending) {
+                removeCallbacksAndMessages(token)
+            }
+            post(token) {
+                detachSurfaceSessionInternal(token, callback)
+            }
+        }
+    }
+
+    /**
+     * Cancel all pending requests to all currently managed [SurfaceSession] instances,
+     * destroy all EGLSurfaces, teardown EGLManager and quit this thread
+     */
+    @AnyThread
+    fun tearDown(cancelPending: Boolean, callback: Runnable?) {
+        withHandler {
+            if (cancelPending) {
+                removeCallbacksAndMessages(null)
+            }
+            post {
+                releaseResourcesInternalAndQuit(callback)
+            }
+            mIsTearingDown.set(true)
+        }
+    }
+
+    /**
+     * Mark the corresponding surface session with the given token as dirty
+     * to schedule a call to [RenderCallback#onDrawFrame].
+     * If there is already a queued request to render into the provided surface with
+     * the specified token, this request is ignored.
+     */
+    @AnyThread
+    fun requestRender(token: Int, callback: Runnable? = null) {
+        log("dispatching request to render for token: $token")
+        withHandler {
+            post(token) {
+                requestRenderInternal(token)
+                callback?.run()
+            }
+        }
+    }
+
+    /**
+     * Lazily creates an [EglManager] instance from the given [mEglSpecFactory]
+     * used to determine the configuration. This result is cached across calls
+     * unless [tearDown] has been called.
+     */
+    @WorkerThread
+    fun obtainEglManager(): EglManager =
+        mEglManager ?: EglManager(mEglSpecFactory.invoke()).also {
+            it.initialize()
+            val config = mEglConfigFactory.invoke(it)
+            it.createContext(config)
+            for (callback in mEglContextCallback) {
+                callback.onEglContextCreated(it)
+            }
+            mEglManager = it
+        }
+
+    @WorkerThread
+    private fun disposeSurfaceSession(session: SurfaceSession) {
+        val eglSurface = session.eglSurface
+        if (eglSurface != null && eglSurface != EGL14.EGL_NO_SURFACE) {
+            obtainEglManager().eglSpec.eglDestroySurface(eglSurface)
+            session.eglSurface = null
+        }
+    }
+
+    /**
+     * Helper method to obtain the cached EGLSurface for the given [SurfaceSession],
+     * creating one if it does not previously exist
+     */
+    @WorkerThread
+    private fun obtainEglSurfaceForSession(session: SurfaceSession): EGLSurface =
+        session.eglSurface ?: createEglSurfaceForSession(session)
+
+    /**
+     * Helper method to create the corresponding EGLSurface from the [SurfaceSession] instance
+     * Consumers are expected to teardown the previously existing EGLSurface instance if it exists
+     */
+    @WorkerThread
+    private fun createEglSurfaceForSession(
+        session: SurfaceSession
+    ): EGLSurface {
+        with(obtainEglManager()) {
+            val eglSurface = session.surfaceRenderer.onSurfaceCreated(
+                eglSpec,
+                // Successful creation of EglManager ensures non null EGLConfig
+                eglConfig!!,
+                session.surface,
+                session.width,
+                session.height
+            )
+            session.eglSurface = eglSurface
+            return eglSurface
+        }
+    }
+
+    @WorkerThread
+    private fun releaseResourcesInternalAndQuit(callback: Runnable?) {
+        mEglManager?.let { eglManager ->
+            for (session in mSurfaceSessions) {
+                disposeSurfaceSession(session.value)
+            }
+            callback?.run()
+            mSurfaceSessions.clear()
+            for (eglCallback in mEglContextCallback) {
+                eglCallback.onEglContextDestroyed(eglManager)
+            }
+            mEglContextCallback.clear()
+            eglManager.release()
+            mEglManager = null
+            quit()
+        }
+    }
+
+    @WorkerThread
+    private fun requestRenderInternal(token: Int) {
+        log("requesting render for token: $token")
+        mSurfaceSessions[token]?.let { surfaceSession ->
+            val eglManager = obtainEglManager()
+            eglManager.makeCurrent(obtainEglSurfaceForSession(surfaceSession))
+            val width = surfaceSession.width
+            val height = surfaceSession.height
+            if (width > 0 && height > 0) {
+                surfaceSession.surfaceRenderer.onDrawFrame(eglManager)
+            }
+            eglManager.swapAndFlushBuffers()
+        }
+    }
+
+    @WorkerThread
+    private fun attachSurfaceSessionInternal(surfaceSession: SurfaceSession) {
+        mSurfaceSessions[surfaceSession.surfaceToken] = surfaceSession
+    }
+
+    @WorkerThread
+    private fun resizeSurfaceSessionInternal(
+        token: Int,
+        width: Int,
+        height: Int
+    ) {
+        mSurfaceSessions[token]?.let { surfaceSession ->
+            surfaceSession.apply {
+                this.width = width
+                this.height = height
+            }
+            disposeSurfaceSession(surfaceSession)
+            obtainEglSurfaceForSession(surfaceSession)
+        }
+    }
+
+    @WorkerThread
+    private fun detachSurfaceSessionInternal(token: Int, callback: Runnable?) {
+        val session = mSurfaceSessions.remove(token)
+        if (session != null) {
+            disposeSurfaceSession(session)
+        }
+        callback?.run()
+    }
+
+    /**
+     * Helper method that issues a callback on the handler instance for this thread
+     * ensuring proper nullability checks are handled.
+     * This assumes that that [GLRenderer.start] has been called before attempts
+     * to interact with the corresponding Handler are made with this method
+     */
+    private inline fun withHandler(block: Handler.() -> Unit) {
+        val handler = mHandler
+            ?: throw IllegalStateException("Did you forget to call GLThread.start()?")
+        if (!mIsTearingDown.get()) {
+            block(handler)
+        }
+    }
+
+    companion object {
+
+        private const val DEBUG = true
+        private const val TAG = "GLThread"
+        internal fun log(msg: String) {
+            if (DEBUG) {
+                Log.v(TAG, msg)
+            }
+        }
+    }
+
+    private class SurfaceSession(
+        /**
+         * Identifier used to lookup the mapping of this surface session.
+         * Consumers are expected to provide this identifier to operate on the corresponding
+         * surface to either request a frame be rendered or to remove this Surface
+         */
+        val surfaceToken: Int,
+
+        /**
+         * Target surface to render into
+         */
+        val surface: Surface,
+
+        /**
+         * Callback used to create an EGLSurface from the provided surface as well as
+         * render content to the surface
+         */
+        val surfaceRenderer: RenderCallback
+    ) {
+        /**
+         * Lazily created + cached [EGLSurface] after [RenderCallback.onSurfaceCreated]
+         * is invoked. This is  only modified on the backing thread
+         */
+        var eglSurface: EGLSurface? = null
+
+        /**
+         * Target width of the [surface]. This is only modified on the backing thread
+         */
+        var width: Int = 0
+
+        /**
+         * Target height of the [surface]. This is only modified on the backing thread
+         */
+        var height: Int = 0
+    }
+
+    /**
+     * Handler does not expose a post method that takes a token and a runnable.
+     * We need the token to be able to cancel pending requests so just call
+     * postAtTime with the default of SystemClock.uptimeMillis
+     */
+    private fun Handler.post(token: Any?, runnable: Runnable) {
+        postAtTime(runnable, token, SystemClock.uptimeMillis())
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EGLHandle.kt b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EGLHandle.kt
new file mode 100644
index 0000000..e9fca27
--- /dev/null
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EGLHandle.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2022 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.graphics.opengl.egl
+
+/**
+ * Interface used to wrap native EGL objects to create type safe objects
+ */
+@Suppress("AcronymName")
+interface EGLHandle {
+    /**
+     * Returns the native handle of the wrapped EGL object. This handle can be
+     * cast to the corresponding native type on the native side.
+     *
+     * For example, EGLDisplay dpy = (EGLDisplay)handle;
+     *
+     * @return the native handle of the wrapped EGL object.
+     */
+    val nativeHandle: Long
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EGLImageKHR.kt b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EGLImageKHR.kt
new file mode 100644
index 0000000..84f62ef
--- /dev/null
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EGLImageKHR.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2022 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.graphics.opengl.egl
+
+/**
+ * EGLImageKHR is an object which can be used to create EGLImage
+ * target resources (inside client APIs).
+ * This is similar to EGL's EGLImage API except the KHR suffix indicates it is generated
+ * as part of the extension APIs namely through [EGLUtils.eglCreateImageFromHardwareBuffer]
+ */
+@Suppress("AcronymName")
+class EGLImageKHR(override val nativeHandle: Long) : EGLHandle {
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is EGLImageKHR) return false
+
+        if (nativeHandle != other.nativeHandle) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        return nativeHandle.hashCode()
+    }
+
+    override fun toString(): String {
+        return "EGLImageKHR(nativeHandle=$nativeHandle)"
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EGLSyncKHR.kt b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EGLSyncKHR.kt
new file mode 100644
index 0000000..84fb5c7
--- /dev/null
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EGLSyncKHR.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2022 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.graphics.opengl.egl
+
+/**
+ * EGLHandle to wrap native EGLSync objects.
+ * This is similar to EGL's EGLSync API except the KHR suffix indicates it is generated
+ * as part of the extension APIs namely through [EGLUtils.eglCreateSyncKHR].
+ */
+@Suppress("AcronymName")
+class EGLSyncKHR(override val nativeHandle: Long) : EGLHandle {
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is EGLSyncKHR) return false
+
+        if (nativeHandle != other.nativeHandle) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        return nativeHandle.hashCode()
+    }
+
+    override fun toString(): String {
+        return "EGLSyncKHR(nativeHandle=$nativeHandle)"
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EGLUtils.kt b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EGLUtils.kt
new file mode 100644
index 0000000..e5466de
--- /dev/null
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EGLUtils.kt
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2022 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.graphics.opengl.egl
+
+import android.hardware.HardwareBuffer
+import android.opengl.EGLDisplay
+import android.os.Build
+import androidx.annotation.RequiresApi
+
+/**
+ * Utility class that provides some helper methods for interacting EGL Extension APIs
+ */
+@Suppress("AcronymName")
+class EGLUtils private constructor() {
+
+    companion object {
+
+        /**
+         * This extension enables the creation of EGL fence sync objects that are
+         * associated with a native synchronization fence object that is referenced
+         * using a file descriptor.  These EGL fence sync objects have nearly
+         * identical semantics to those defined by the KHR_fence_sync extension,
+         * except that they have an additional attribute storing the file descriptor
+         * referring to the native fence object.
+         *
+         * This extension assumes the existence of a native fence synchronization
+         * object that behaves similarly to an EGL fence sync object.  These native
+         * objects must have a signal status like that of an EGLSyncKHR object that
+         * indicates whether the fence has ever been signaled.  Once signaled the
+         * native object's signal status may not change again.
+         *
+         * See:
+         * https://www.khronos.org/registry/EGL/extensions/ANDROID/EGL_ANDROID_native_fence_sync.txt
+         */
+        const val EGL_SYNC_NATIVE_FENCE_ANDROID = 12612
+
+        /**
+         * Creates an EGLImage from the provided [HardwareBuffer]. This handles
+         * internally creating an EGLClientBuffer and an EGLImage from the client buffer.
+         *
+         * @param eglDisplay EGLDisplay connection associated with the EGLImage to create
+         * @param hardwareBuffer Backing [HardwareBuffer] for the generated EGLImage instance
+         *
+         * @return an EGLImageKHR instance representing the EGLImage created from the HardwareBuffer
+         * Because this is created internally through EGL's eglCreateImageKR method, this has the
+         * KHR suffix.
+         */
+        @JvmStatic
+        @RequiresApi(Build.VERSION_CODES.O)
+        fun eglCreateImageFromHardwareBuffer(
+            eglDisplay: EGLDisplay,
+            hardwareBuffer: HardwareBuffer
+        ): EGLImageKHR? {
+            val handle = EGLUtilsBindings.nCreateImageFromHardwareBuffer(
+                eglDisplay.obtainNativeHandle(), hardwareBuffer)
+            return if (handle == 0L) {
+                null
+            } else {
+                EGLImageKHR(handle)
+            }
+        }
+
+        /**
+         * Destroy the given EGLImageKHR instance. Once destroyed, the image may not be used to
+         * create any additional EGLImage target resources within any client API contexts,
+         * although existing EGLImage siblings may continue to be used. True is returned
+         * if DestroyImageKHR succeeds, false indicates failure. This can return false if
+         * the EGLImage is not associated with the default display.
+         *
+         * See: https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_image_base.txt
+         *
+         * @param eglDisplay EGLDisplay that this EGLImage is connected to
+         * @param image EGLImageKHR to be destroyed
+         *
+         * @return True if the destruction of the EGLImageKHR object was successful, false otherwise
+         */
+        @JvmStatic
+        @Suppress("AcronymName")
+        fun eglDestroyImageKHR(
+            eglDisplay: EGLDisplay,
+            image: EGLImageKHR
+        ): Boolean = EGLUtilsBindings.nDestroyImageKHR(
+            eglDisplay.obtainNativeHandle(),
+            image.nativeHandle
+        )
+
+        /**
+         * Upload a given EGLImage to the currently bound GLTexture
+         *
+         * This method requires either of the following EGL extensions to be supported:
+         * EGL_KHR_image_base or EGL_KHR_image
+         *
+         * See: https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external.txt
+         */
+        @JvmStatic
+        @Suppress("AcronymName")
+        fun glEGLImageTargetTexture2DOES(target: Int, image: EGLImageKHR) {
+            EGLUtilsBindings.nImageTargetTexture2DOES(target, image.nativeHandle)
+        }
+
+        /**
+         * Creates a sync object of the specified type associated with the
+         * specified display, and returns a handle to the new object.
+         * The configuration of the returned [EGLSyncKHR] object is specified by the provided
+         * attributes.
+         *
+         * Consumers should ensure that the EGL_KHR_fence_sync EGL extension is supported before
+         * invoking this method otherwise a null EGLSyncFenceKHR object is returned.
+         *
+         * See: https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_fence_sync.txt
+         *
+         * @param eglDisplay EGLDisplay to associate the sync object with
+         * @param type Indicates the type of sync object that is returned
+         * @param attributes Specifies the configuration of the sync object returned
+         *
+         * @return the EGLSyncKHR object to be used as a fence or null if this extension
+         * is not supported
+         */
+        @JvmStatic
+        @Suppress("AcronymName")
+        fun eglCreateSyncKHR(
+            eglDisplay: EGLDisplay,
+            type: Int,
+            attributes: EglConfigAttributes?
+        ): EGLSyncKHR? {
+            val handle = EGLUtilsBindings.nCreateSyncKHR(
+                eglDisplay.obtainNativeHandle(), type, attributes?.attrs)
+            return if (handle == 0L) {
+                null
+            } else {
+                EGLSyncKHR(handle)
+            }
+        }
+
+        /**
+         * Destroys the given sync object associated with the specified display
+         *
+         * Consumers should ensure that the EGL_KHR_fence_sync EGL extension is supported before
+         * invoking this method otherwise a null EGLSyncFenceKHR object is returned.
+         * See: https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_fence_sync.txt
+         *
+         * @param eglDisplay EGLDisplay instance associated with the fence
+         * @param eglSync Fence object to be destroyed
+         *
+         * @return true if the EGLSyncKHR object was destroyed successfully false otherwise. This
+         * can return false if the sync object is not a valid sync object for the provided display
+         * or if the display provided in this method does not match the display used to create this
+         * sync in eglCreateSyncKHR.
+         */
+        @JvmStatic
+        @Suppress("AcronymName")
+        fun eglDestroySyncKHR(
+            eglDisplay: EGLDisplay,
+            eglSync: EGLSyncKHR
+        ): Boolean = EGLUtilsBindings.nDestroySyncKHR(
+            eglDisplay.obtainNativeHandle(),
+            eglSync.nativeHandle
+        )
+
+        /**
+         * Helper method to obtain the corresponding native handle. Newer versions of Android
+         * represent the native pointer as a long instead of an integer to support 64 bits.
+         * For OS levels that support the wider bit format, invoke it otherwise cast the int
+         * to a long.
+         *
+         * This is internal to avoid synthetic accessors
+         */
+        internal fun EGLDisplay.obtainNativeHandle(): Long =
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+                EGLDisplayVerificationHelper.getNativeHandle(this)
+            } else {
+                @Suppress("DEPRECATION")
+                handle.toLong()
+            }
+    }
+}
+
+/**
+ * Helper class to configure JNI bindings to be invoked within the EGLUtils
+ * public API. This class is provided to separate responsibilities of jni method registration
+ * and helps to avoid synthetic accessor warnings
+ */
+internal class EGLUtilsBindings {
+    companion object {
+        external fun nCreateImageFromHardwareBuffer(
+            eglDisplayPtr: Long,
+            hardwareBuffer: HardwareBuffer
+        ): Long
+
+        // Note this API is explicitly a GL API and not an EGL API which is the reason
+        // why this has the GL prefix vs EGL
+        external fun nImageTargetTexture2DOES(target: Int, eglImagePtr: Long)
+        external fun nCreateSyncKHR(eglDisplayPtr: Long, type: Int, attrs: IntArray?): Long
+        external fun nDestroySyncKHR(eglDisplayPtr: Long, syncPtr: Long): Boolean
+        external fun nDestroyImageKHR(eglDisplayPtr: Long, eglImagePtr: Long): Boolean
+        external fun nSupportsEglGetNativeClientBufferAndroid(): Boolean
+        external fun nSupportsEglCreateImageKHR(): Boolean
+        external fun nSupportsEglDestroyImageKHR(): Boolean
+        external fun nSupportsGlImageTargetTexture2DOES(): Boolean
+        external fun nSupportsEglCreateSyncKHR(): Boolean
+        external fun nSupportsEglDestroySyncKHR(): Boolean
+
+        init {
+            System.loadLibrary("graphics-core")
+        }
+    }
+}
+
+/**
+ * Helper class to avoid class verification failures
+ */
+@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
+private class EGLDisplayVerificationHelper private constructor() {
+
+    companion object {
+        @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
+        @androidx.annotation.DoNotInline
+        fun getNativeHandle(eglDisplay: EGLDisplay): Long = eglDisplay.nativeHandle
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EglConfigAttributes.kt b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EglConfigAttributes.kt
new file mode 100644
index 0000000..883b2e8
--- /dev/null
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EglConfigAttributes.kt
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ * 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.graphics.opengl.egl
+
+import android.opengl.EGL14
+
+/**
+ * EGL configuration attribute used to expose EGLConfigs that support formats with floating point
+ * RGBA components. This attribute is exposed through the EGL_EXT_pixel_format_float EGL extension
+ *
+ * See: https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_pixel_format_float.txt
+ */
+const val EglColorComponentTypeExt = 0x3339
+
+/**
+ * EGL configuration attribute value that represents fixed point RGBA components
+ */
+const val EglColorComponentTypeFixedExt = 0x333A
+
+/**
+ * EGL configuration attribute value that represents floating point RGBA components
+ */
+const val EglColorComponentTypeFloatExt = 0x333B
+
+/**
+ * EGL Attributes to create an 8 bit EGL config for red, green, blue, and alpha channels as well
+ * as an 8 bit stencil size
+ */
+val EglConfigAttributes8888 = EglConfigAttributes {
+    EGL14.EGL_RENDERABLE_TYPE to EGL14.EGL_OPENGL_ES2_BIT
+    EGL14.EGL_RED_SIZE to 8
+    EGL14.EGL_GREEN_SIZE to 8
+    EGL14.EGL_BLUE_SIZE to 8
+    EGL14.EGL_ALPHA_SIZE to 8
+    EGL14.EGL_DEPTH_SIZE to 0
+    EGL14.EGL_CONFIG_CAVEAT to EGL14.EGL_NONE
+    EGL14.EGL_STENCIL_SIZE to 0
+    EGL14.EGL_SURFACE_TYPE to EGL14.EGL_WINDOW_BIT
+}
+
+/**
+ * EGL Attributes to create a 10 bit EGL config for red, green, blue, channels and a
+ * 2 bit alpha channels as well as an 8 bit stencil size
+ */
+val EglConfigAttributes1010102 = EglConfigAttributes {
+    EGL14.EGL_RENDERABLE_TYPE to EGL14.EGL_OPENGL_ES2_BIT
+    EGL14.EGL_RED_SIZE to 10
+    EGL14.EGL_GREEN_SIZE to 10
+    EGL14.EGL_BLUE_SIZE to 10
+    EGL14.EGL_ALPHA_SIZE to 2
+    EGL14.EGL_DEPTH_SIZE to 0
+    EGL14.EGL_STENCIL_SIZE to 0
+    EGL14.EGL_SURFACE_TYPE to EGL14.EGL_WINDOW_BIT
+}
+
+/**
+ * EGL Attributes to create a 16 bit floating point EGL config for red, green and blue channels
+ * along with a
+ */
+val EglConfigAttributesF16 = EglConfigAttributes {
+    EGL14.EGL_RENDERABLE_TYPE to EGL14.EGL_OPENGL_ES2_BIT
+    EglColorComponentTypeExt to EglColorComponentTypeFloatExt
+    EGL14.EGL_RED_SIZE to 16
+    EGL14.EGL_GREEN_SIZE to 16
+    EGL14.EGL_BLUE_SIZE to 16
+    EGL14.EGL_ALPHA_SIZE to 16
+    EGL14.EGL_DEPTH_SIZE to 0
+    EGL14.EGL_STENCIL_SIZE to 0
+    EGL14.EGL_SURFACE_TYPE to EGL14.EGL_WINDOW_BIT
+}
+
+/**
+ * Construct an instance of [EglConfigAttributes] that includes a mapping of EGL attributes
+ * to their corresponding value. The full set of attributes can be found here:
+ * https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglChooseConfig.xhtml
+ *
+ * The resultant array of attributes automatically is terminated with EGL_NONE.
+ *
+ * For example to create an 8888 configuration, this can be done with the following:
+ *
+ * EglConfigAttributes {
+ *      EGL14.EGL_RENDERABLE_TYPE to EGL14.EGL_OPENGL_ES2_BIT
+ *      EGL14.EGL_RED_SIZE to 8
+ *      EGL14.EGL_GREEN_SIZE to 8
+ *      EGL14.EGL_BLUE_SIZE to 8
+ *      EGL14.EGL_ALPHA_SIZE to 8
+ *      EGL14.EGL_DEPTH_SIZE to 0
+ *      EGL14.EGL_CONFIG_CAVEAT to EGL14.EGL_NONE
+ *      EGL14.EGL_STENCIL_SIZE to 8
+ *      EGL14.EGL_SURFACE_TYPE to EGL14.EGL_WINDOW_BIT
+ * }
+ *
+ * @see EglConfigAttributes8888
+ */
+inline fun EglConfigAttributes(block: EglConfigAttributes.Builder.() -> Unit): EglConfigAttributes =
+    EglConfigAttributes.Builder().apply { block() }.build()
+
+// klint does not support value classes yet, see b/197692691
+@Suppress("INLINE_CLASS_DEPRECATED")
+inline class EglConfigAttributes internal constructor(
+    @PublishedApi internal val attrs: IntArray
+) {
+
+    /**
+     * Builder used to create an instance of [EglConfigAttributes]
+     * Allows for a mapping of EGL configuration attributes to their corresponding
+     * values as well as including a previously generated [EglConfigAttributes]
+     * instance to be used as a template and conditionally update individual mapped values
+     */
+    // Suppressing build method as EglConfigAttributes is created using Kotlin DSL syntax
+    // via the function constructor defined above
+    @SuppressWarnings("MissingBuildMethod")
+    class Builder @PublishedApi internal constructor() {
+        private val attrs = HashMap<Int, Int>()
+
+        /**
+         * Map a given EGL configuration attribute key to the given EGL configuration value
+         */
+        @SuppressWarnings("BuilderSetStyle")
+        infix fun Int.to(that: Int) {
+            attrs[this] = that
+        }
+
+        /**
+         * Include all the attributes of the given EglConfigAttributes instance.
+         * This is useful for creating a new EglConfigAttributes instance with all the same
+         * attributes as another, allowing for modification of attributes after the fact.
+         * For example, the following code snippet can be used to create an EglConfigAttributes
+         * instance that has all the same configuration as [EglConfigAttributes8888] but with a
+         * 16 bit stencil buffer size:
+         *
+         * EglConfigAttributes {
+         *      include(EglConfigAttributes8888)
+         *      EGL14.EGL_STENCIL_SIZE to 16
+         * }
+         *
+         *
+         * That is all attributes configured after the include will overwrite the attributes
+         * configured previously.
+         */
+        @SuppressWarnings("BuilderSetStyle")
+        fun include(attributes: EglConfigAttributes) {
+            val attrsArray = attributes.attrs
+            for (i in 0 until attrsArray.size - 1 step 2) {
+                attrs[attrsArray[i]] = attrsArray[i + 1]
+            }
+        }
+
+        @PublishedApi internal fun build(): EglConfigAttributes {
+            val entries = attrs.entries
+            val attrArray = IntArray(entries.size * 2 + 1) // Array must end with EGL_NONE
+            var index = 0
+            for (entry in entries) {
+                attrArray[index] = entry.key
+                attrArray[index + 1] = entry.value
+                index += 2
+            }
+            attrArray[index] = EGL14.EGL_NONE
+            return EglConfigAttributes(attrArray)
+        }
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EglExtensions.kt b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EglExtensions.kt
new file mode 100644
index 0000000..9231d59
--- /dev/null
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EglExtensions.kt
@@ -0,0 +1,212 @@
+/*
+ * 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.
+ * 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.graphics.opengl.egl
+
+/**
+ * Determines if applications can query the age of the back buffer contents for an
+ * EGL surface as the number of frames elapsed since the contents were recently defined
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_buffer_age.txt
+ */
+const val EglExtBufferAge = "EGL_EXT_buffer_age"
+
+/**
+ * Allows for efficient partial updates to an area of a **buffer** that has changed since
+ * the last time the buffer was used
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_partial_update.txt
+ */
+const val EglKhrPartialUpdate = "EGL_KHR_partial_update"
+
+/**
+ * Allows for efficient partial updates to an area of a **surface** that changes between
+ * frames for the surface. This relates to the differences between two buffers, the current
+ * back buffer and the current front buffer.
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_swap_buffers_with_damage.txt
+ */
+const val EglKhrSwapBuffersWithDamage = "EGL_KHR_swap_buffers_with_damage"
+
+/**
+ * Determines whether to use sRGB format default framebuffers to render sRGB
+ * content to display devices. Supports creation of EGLSurfaces which will be rendered to in
+ * sRGB by OpenGL contexts supporting that capability.
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_gl_colorspace.txt
+ */
+const val EglKhrGlColorSpace = "EGL_KHR_gl_colorspace"
+
+/**
+ * Determines whether creation of GL and ES contexts without an EGLConfig is allowed
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_no_config_context.txt
+ */
+const val EglKhrNoConfigContext = "EGL_KHR_no_config_context"
+
+/**
+ * Determines whether floating point RGBA components are supported
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_pixel_format_float.txt
+ */
+const val EglExtPixelFormatFloat = "EGL_EXT_pixel_format_float"
+
+/**
+ * Determines whether extended sRGB color spaces are supported options for EGL Surfaces
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_gl_colorspace_scrgb.txt
+ */
+const val EglExtGlColorSpaceScRgb = "EGL_EXT_gl_colorspace_scrgb"
+
+/**
+ * Determines whether the underlying platform can support rendering framebuffers in the
+ * non-linear Display-P3 color space
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_gl_colorspace_display_p3_passthrough.txt
+ */
+const val EglExtColorSpaceDisplayP3Passthrough = "EGL_EXT_gl_colorspace_display_p3_passthrough"
+
+/**
+ * Determines whether the platform framebuffers support rendering in a larger color gamut
+ * specified in the BT.2020 color space
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_gl_colorspace_bt2020_linear.txt
+ */
+const val EglExtGlColorSpaceBt2020Pq = "EGL_EXT_gl_colorspace_bt2020_pq"
+
+/**
+ * Determines whether an EGLContext can be created with a priority hint. Not all implementations
+ * are guaranteed to honor the hint.
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/IMG/EGL_IMG_context_priority.txt
+ */
+const val EglImgContextPriority = "EGL_IMG_context_priority"
+
+/**
+ * Determines whether creation of an EGL Context without a surface is supported.
+ * This is useful for applications that only want to render to client API targets (such as
+ * OpenGL framebuffer objects) and avoid the need to a throw-away EGL surface just to get
+ * a current context.
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_surfaceless_context.txt
+ */
+const val EglKhrSurfacelessContext = "EGL_KHR_surfaceless_context"
+
+/**
+ * Determines whether sync objects are supported. Sync objects are synchronization primitives
+ * that represent events whose completion can be tested or waited upon.
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_fence_sync.txt
+ */
+const val EglKhrFenceSync = "EGL_KHR_fence_sync"
+
+/**
+ * Determines whether waiting for signaling of sync objects is supported. This form of wait
+ * does not necessarily block the application thread which issued the wait. Therefore
+ * applications may continue to issue commands to the client API or perform other work
+ * in parallel leading to increased performance.
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_wait_sync.txt
+ */
+const val EglKhrWaitSync = "EGL_KHR_wait_sync"
+
+/**
+ * Determines whether creation of platform specific sync objects are supported. These
+ * objects that are associated with a native synchronization fence object using a file
+ * descriptor.
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/ANDROID/EGL_ANDROID_native_fence_sync.txt
+ */
+const val EglAndroidNativeFenceSync = "EGL_ANDROID_native_fence_sync"
+
+/**
+ * Enables using an Android window buffer (struct ANativeWindowBuffer) as an EGLImage source
+ *
+ * See: https://www.khronos.org/registry/EGL/extensions/ANDROID/EGL_ANDROID_image_native_buffer.txt
+ */
+const val EglAndroidImageNativeBuffer = "EGL_ANDROID_image_native_buffer"
+
+/**
+ * Extension for supporting a new EGL resource type that is suitable for
+ * sharing 2D arrays of image data between client APIs, the EGLImage.
+ * Although the intended purpose is sharing 2D image data, the
+ * underlying interface makes no assumptions about the format or
+ * purpose of the resource being shared, leaving those decisions to
+ * the application and associated client APIs.
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_image_base.txt
+ */
+const val EglKhrImageBase = "EGL_KHR_image_base"
+
+/**
+ * Extension that defines a new EGL resource type that is suitable for
+ * sharing 2D arrays of image data between client APIs, the EGLImage,
+ * and allows creating EGLImages from EGL native pixmaps.
+ *
+ * See:
+ * https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_image.txt
+ */
+const val EglKhrImage = "EGL_KHR_image"
+
+/**
+ * Class determining the types of OpenGL extensions supported by the given
+ * EGL spec.
+ */
+// klint does not support value classes yet, see b/197692691
+@Suppress("INLINE_CLASS_DEPRECATED")
+inline class EglExtensions(
+    private val extensionSet: Set<String>
+) {
+
+    /**
+     * Determines whether the extension with the provided name is supported. The string
+     * provided is expected to be one of the named extensions defined within the OpenGL
+     * extension documentation.
+     *
+     * Returns true if the extension is supported, false otherwise
+     */
+    fun isExtensionSupported(extensionName: String): Boolean =
+        extensionSet.contains(extensionName)
+
+    companion object {
+
+        /**
+         * Creates an instance of [EglExtensions] from a space separated string
+         * that represents the set of OpenGL extensions supported
+         */
+        @JvmStatic
+        fun from(queryString: String): EglExtensions =
+            HashSet<String>().let {
+                it.addAll(queryString.split(' '))
+                EglExtensions(it)
+            }
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EglManager.kt b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EglManager.kt
new file mode 100644
index 0000000..da3e7c5
--- /dev/null
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EglManager.kt
@@ -0,0 +1,229 @@
+/*
+ * 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.
+ * 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.graphics.opengl.egl
+
+import android.opengl.EGL14
+import android.opengl.EGLConfig
+import android.opengl.EGLContext
+import android.opengl.EGLSurface
+import android.opengl.GLES20
+
+/**
+ * Class responsible for configuration of EGL related resources. This includes
+ * initialization of the corresponding EGL Display as well as EGL Context, among
+ * other EGL related facilities.
+ */
+class EglManager(val eglSpec: EglSpec = EglSpec.Egl14) {
+
+    private var mEglConfig: EGLConfig? = null
+
+    /**
+     * Offscreen pixel buffer surface
+     */
+    private var mPBufferSurface: EGLSurface = EGL14.EGL_NO_SURFACE
+    private var mEglContext: EGLContext = EGL14.EGL_NO_CONTEXT
+    private var mWideColorGamutSupport = false
+    private var mEglVersion = EglVersion.Unknown
+    private var mEglExtensions: EglExtensions? = null
+    private var mIsSingleBuffered: Boolean = false
+    private var mQueryResult: IntArray? = null
+
+    /**
+     * Initialize the EGLManager. This initializes the default display as well
+     * as queries the supported extensions
+     */
+    fun initialize() {
+        mEglContext.let {
+            if (it === EGL14.EGL_NO_CONTEXT) {
+                mEglVersion = eglSpec.eglInitialize()
+                mEglExtensions = EglExtensions.from(eglSpec.eglQueryString(EGL14.EGL_EXTENSIONS))
+            }
+        }
+    }
+
+    /**
+     * Attempt to load an [EGLConfig] instance from the given
+     * [EglConfigAttributes]. If the [EGLConfig] could not be loaded
+     * this returns null
+     */
+    fun loadConfig(configAttributes: EglConfigAttributes): EGLConfig? =
+        eglSpec.loadConfig(configAttributes)
+
+    /**
+     * Creates an [EGLContext] from the given [EGLConfig] returning
+     * null if the context could not be created
+     *
+     * @throws EglException if the default surface could not be made current after context creation
+     */
+    fun createContext(config: EGLConfig): EGLContext {
+        val eglContext = eglSpec.eglCreateContext(config)
+        if (eglContext !== EGL14.EGL_NO_CONTEXT) {
+            val pbBufferSurface: EGLSurface = if (isExtensionSupported(EglKhrSurfacelessContext)) {
+                EGL14.EGL_NO_SURFACE
+            } else {
+                val configAttrs = EglConfigAttributes {
+                    EGL14.EGL_WIDTH to 1
+                    EGL14.EGL_HEIGHT to 1
+                }
+                eglSpec.eglCreatePBufferSurface(config, configAttrs)
+            }
+            if (!eglSpec.eglMakeCurrent(eglContext, pbBufferSurface, pbBufferSurface)) {
+                throw EglException(eglSpec.eglGetError(), "Unable to make default surface current")
+            }
+            mPBufferSurface = pbBufferSurface
+            mEglContext = eglContext
+            mEglConfig = config
+        } else {
+            mPBufferSurface = EGL14.EGL_NO_SURFACE
+            mEglContext = EGL14.EGL_NO_CONTEXT
+            mEglConfig = null
+        }
+        return eglContext
+    }
+
+    /**
+     * Release the resources allocated by EGLManager. This will destroy the corresponding
+     * EGLContext instance if it was previously initialized.
+     * The configured EGLVersion as well as EGLExtensions
+     */
+    fun release() {
+        mEglContext.let {
+            if (it != EGL14.EGL_NO_CONTEXT) {
+                eglSpec.eglDestroyContext(it)
+                mPBufferSurface.let { pbBufferSurface ->
+                    if (pbBufferSurface != EGL14.EGL_NO_SURFACE) {
+                        eglSpec.eglDestroySurface(pbBufferSurface)
+                    }
+                }
+                mPBufferSurface = EGL14.EGL_NO_SURFACE
+                eglSpec.eglMakeCurrent(
+                    EGL14.EGL_NO_CONTEXT,
+                    EGL14.EGL_NO_SURFACE,
+                    EGL14.EGL_NO_SURFACE
+                )
+                mEglVersion = EglVersion.Unknown
+                mEglContext = EGL14.EGL_NO_CONTEXT
+                mEglConfig = null
+                mEglExtensions = null
+            }
+        }
+    }
+
+    /**
+     * Returns the EGL version that is supported. This parameter is configured
+     * after [initialize] is invoked.
+     */
+    val eglVersion: EglVersion
+        get() = mEglVersion
+
+    /**
+     * Returns the current EGLContext. This parameter is configured after [initialize] is invoked
+     */
+    val eglContext: EGLContext?
+        get() = mEglContext
+
+    /**
+     * Returns the [EGLConfig] used to load the current [EGLContext].
+     * This is configured after [createContext] is invoked.
+     */
+    val eglConfig: EGLConfig?
+        get() = mEglConfig
+
+    /**
+     * Determines whether the extension with the provided name is supported. The string
+     * provided is expected to be one of the named extensions defined within the OpenGL
+     * extension documentation.
+     *
+     * See [EglExtensions] for additional documentation for given extension name constants
+     * and descriptions.
+     *
+     * The set of supported extensions is configured after [initialize] is invoked.
+     * Attempts to query support for any extension beforehand will return false.
+     */
+    fun isExtensionSupported(extensionName: String): Boolean =
+        mEglExtensions?.isExtensionSupported(extensionName) ?: false
+
+    /**
+     * Binds the current context to the given draw and read surfaces.
+     * The draw surface is used for all operations except for any pixel data read back or
+     * copy operations which are taken from the read surface.
+     *
+     * The same EGLSurface may be specified for both draw and read surfaces.
+     *
+     * If the context is not previously configured, the only valid parameters for the
+     * draw and read surfaces is [EGL14.EGL_NO_SURFACE]. This is useful to make sure there is
+     * always a surface specified and to release the current context without assigning a new one.
+     *
+     * See https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglMakeCurrent.xhtml
+     *
+     * @param drawSurface Surface used for all operations that involve writing pixel information
+     * @param readSurface Surface used for pixel data read back or copy operations. By default this
+     * is the same as [drawSurface]
+     */
+    @JvmOverloads
+    fun makeCurrent(drawSurface: EGLSurface, readSurface: EGLSurface = drawSurface): Boolean {
+        val result = eglSpec.eglMakeCurrent(mEglContext, drawSurface, readSurface)
+        if (result) {
+            querySurface(drawSurface)
+        }
+        return result
+    }
+
+    /**
+     * Post EGL surface color buffer to a native window. If the current drawing surface
+     * is single buffered this will flush the buffer
+     */
+    fun swapAndFlushBuffers() {
+        if (mIsSingleBuffered) {
+            GLES20.glFlush()
+        }
+        eglSpec.eglSwapBuffers(currentDrawSurface)
+    }
+
+    /**
+     * Returns the default surface. This can be an offscreen pixel buffer surface or
+     * [EGL14.EGL_NO_SURFACE] if the surfaceless context extension is supported.
+     */
+    val defaultSurface: EGLSurface
+        get() = mPBufferSurface
+
+    /**
+     * Returns the current surface used for drawing pixel content
+     */
+    val currentDrawSurface: EGLSurface
+        get() = eglSpec.eglGetCurrentDrawSurface()
+
+    /**
+     * Returns the current surface used for reading back or copying pixels
+     */
+    val currentReadSurface: EGLSurface
+        get() = eglSpec.eglGetCurrentReadSurface()
+
+    /**
+     * Helper method to query properties of the given surface
+     */
+    private fun querySurface(surface: EGLSurface) {
+        val resultArray = mQueryResult ?: IntArray(1).also { mQueryResult = it }
+        if (eglSpec.eglQuerySurface(surface, EGL14.EGL_RENDER_BUFFER, resultArray, 0)) {
+            mIsSingleBuffered = resultArray[0] == EGL14.EGL_SINGLE_BUFFER
+        }
+    }
+
+    companion object {
+        private const val TAG = "EglManager"
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EglSpec.kt b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EglSpec.kt
new file mode 100644
index 0000000..b1e9881
--- /dev/null
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/egl/EglSpec.kt
@@ -0,0 +1,399 @@
+/*
+ * 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.
+ * 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.graphics.opengl.egl
+
+import android.opengl.EGL14
+import android.opengl.EGLConfig
+import android.opengl.EGLContext
+import android.opengl.EGLSurface
+import android.view.Surface
+
+/**
+ * Interface for accessing various EGL facilities independent of EGL versions.
+ * That is each EGL version implements this specification.
+ *
+ * EglSpec is not thread safe and is up to the caller of these methods to guarantee thread safety.
+ */
+interface EglSpec {
+
+    /**
+     * Query for the capabilities associated with the given eglDisplay.
+     * The result contains a space separated list of the capabilities.
+     *
+     * @param nameId identifier for the EGL string to query
+     */
+    fun eglQueryString(nameId: Int): String
+
+    /**
+     * Create a Pixel Buffer surface with the corresponding [EglConfigAttributes].
+     * Accepted attributes are defined as part of the OpenGL specification here:
+     * https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglCreatePbufferSurface.xhtml
+     *
+     * If a pixel buffer surface could not be created, [EGL14.EGL_NO_SURFACE] is returned.
+     *
+     * @param config Specifies the EGL Frame buffer configuration that defines the frame buffer
+     * resource available to the surface
+     * @param configAttributes Optional list of attributes for the pixel buffer surface
+     */
+    fun eglCreatePBufferSurface(
+        config: EGLConfig,
+        configAttributes: EglConfigAttributes?
+    ): EGLSurface
+
+    /**
+     * Creates an on screen EGL window surface from the given [Surface] and returns a handle to it.
+     *
+     * See https://khronos.org/registry/EGL/sdk/docs/man/html/eglCreateWindowSurface.xhtml
+     *
+     * @param config Specifies the EGL frame buffer configuration that defines the frame buffer
+     * resource available to the surface
+     * @param surface Android surface to consume rendered content
+     * @param configAttributes Optional list of attributes for the specified surface
+     */
+    fun eglCreateWindowSurface(
+        config: EGLConfig,
+        surface: Surface,
+        configAttributes: EglConfigAttributes?
+    ): EGLSurface
+
+    /**
+     * Destroys an EGL surface.
+     *
+     * If the EGL surface is not current to any thread, eglDestroySurface destroys
+     * it immediately. Otherwise, surface is destroyed when it becomes not current to any thread.
+     * Furthermore, resources associated with a pbuffer surface are not released until all color
+     * buffers of that pbuffer bound to a texture object have been released. Deferral of
+     * surface destruction would still return true as deferral does not indicate a failure condition
+     *
+     * @return True if destruction of the EGLSurface was successful, false otherwise
+     */
+    fun eglDestroySurface(surface: EGLSurface): Boolean
+
+    /**
+     * Binds the current context to the given draw and read surfaces.
+     * The draw surface is used for all operations except for any pixel data read back or copy
+     * operations which are taken from the read surface.
+     *
+     * The same EGLSurface may be specified for both draw and read surfaces.
+     *
+     * See https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglMakeCurrent.xhtml for more
+     * information
+     *
+     * @param drawSurface EGLSurface to draw pixels into.
+     * @param readSurface EGLSurface used for read/copy operations.
+     */
+    fun eglMakeCurrent(
+        context: EGLContext,
+        drawSurface: EGLSurface,
+        readSurface: EGLSurface
+    ): Boolean
+
+    /**
+     * Return the current surface used for reading or copying pixels.
+     * If no context is current, [EGL14.EGL_NO_SURFACE] is returned
+     */
+    fun eglGetCurrentReadSurface(): EGLSurface
+
+    /**
+     * Return the current surface used for drawing pixels.
+     * If no context is current, [EGL14.EGL_NO_SURFACE] is returned.
+     */
+    fun eglGetCurrentDrawSurface(): EGLSurface
+
+    /**
+     * Initialize the EGL implementation and return the major and minor version of the EGL
+     * implementation through [EglVersion]. If initialization fails, this returns
+     * [EglVersion.Unknown]
+     */
+    fun eglInitialize(): EglVersion
+
+    /**
+     * Load a corresponding EGLConfig from the provided [EglConfigAttributes]
+     * If the EGLConfig could not be loaded, null is returned
+     * @param configAttributes Desired [EglConfigAttributes] to create an [EGLConfig]
+     *
+     * @return the [EGLConfig] with the provided [EglConfigAttributes] or null if
+     * an [EGLConfig] could not be created with the specified attributes
+     */
+    fun loadConfig(configAttributes: EglConfigAttributes): EGLConfig?
+
+    /**
+     * Create an EGLContext with the default display. If createContext fails to create a
+     * rendering context, EGL_NO_CONTEXT is returned
+     *
+     * @param config [EGLConfig] used to create the [EGLContext]
+     */
+    fun eglCreateContext(config: EGLConfig): EGLContext
+
+    /**
+     * Destroy the given EGLContext generated in [eglCreateContext]
+     *
+     * See https://khronos.org/registry/EGL/sdk/docs/man/html/eglDestroyContext.xhtml
+     *
+     * @param eglContext EGL rendering context to be destroyed
+     */
+    fun eglDestroyContext(eglContext: EGLContext)
+
+    /**
+     * Post EGL surface color buffer to a native window
+     *
+     * See https://khronos.org/registry/EGL/sdk/docs/man/html/eglSwapBuffers.xhtml
+     *
+     * @param surface Specifies the EGL drawing surface whose buffers are to be swapped
+     *
+     * @return True if swapping of buffers succeeds, false otherwise
+     */
+    fun eglSwapBuffers(surface: EGLSurface): Boolean
+
+    /**
+     * Query the EGL attributes of the provided surface
+     *
+     * @param surface EGLSurface to be queried
+     * @param attribute EGL attribute to query on the given EGL Surface
+     * @param result Int array to store the result of the query
+     * @param offset Index within [result] to store the value of the queried attribute
+     *
+     * @return True if the query was completed successfully, false otherwise. If the query
+     * fails, [result] is unmodified
+     */
+    fun eglQuerySurface(surface: EGLSurface, attribute: Int, result: IntArray, offset: Int): Boolean
+
+    /**
+     * Returns the error of the last called EGL function in the current thread. Initially,
+     * the error is set to EGL_SUCCESS. When an EGL function could potentially generate several
+     * different errors (for example, when passed both a bad attribute name, and a bad attribute
+     * value for a legal attribute name), the implementation may choose to generate any one of the
+     * applicable errors.
+     *
+     * See https://khronos.org/registry/EGL/sdk/docs/man/html/eglGetError.xhtml for more information
+     * and error codes that could potentially be returned
+     */
+    fun eglGetError(): Int
+
+    /**
+     * Convenience method to obtain the corresponding error string from the
+     * error code obtained from [EglSpec.eglGetError]
+     */
+    fun getErrorMessage(): String = getStatusString(eglGetError())
+
+    companion object {
+
+        @JvmField
+        val Egl14 = object : EglSpec {
+
+            // Tuples of attribute identifiers along with their corresponding values.
+            // EGL_NONE is used as a termination value similar to a null terminated string
+            private val contextAttributes = intArrayOf(
+                EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, // GLES VERSION 2
+                // HWUI provides the ability to configure a context priority as well but that only
+                // seems to be configured on SystemUIApplication. This might be useful for
+                // front buffer rendering situations for performance.
+                EGL14.EGL_NONE
+            )
+
+            override fun eglInitialize(): EglVersion {
+                // eglInitialize is destructive so create 2 separate arrays to store the major and
+                // minor version
+                val major = intArrayOf(1)
+                val minor = intArrayOf(1)
+                val initializeResult =
+                    EGL14.eglInitialize(getDefaultDisplay(), major, 0, minor, 0)
+                if (initializeResult) {
+                    return EglVersion(major[0], minor[0])
+                } else {
+                    throw EglException(EGL14.eglGetError(), "Unable to initialize default display")
+                }
+            }
+
+            override fun eglGetCurrentReadSurface(): EGLSurface =
+                EGL14.eglGetCurrentSurface(EGL14.EGL_READ)
+
+            override fun eglGetCurrentDrawSurface(): EGLSurface =
+                EGL14.eglGetCurrentSurface(EGL14.EGL_DRAW)
+
+            override fun eglQueryString(nameId: Int): String =
+                EGL14.eglQueryString(getDefaultDisplay(), nameId)
+
+            override fun eglCreatePBufferSurface(
+                config: EGLConfig,
+                configAttributes: EglConfigAttributes?
+            ): EGLSurface =
+                EGL14.eglCreatePbufferSurface(
+                    getDefaultDisplay(),
+                    config,
+                    configAttributes?.attrs,
+                    0
+                )
+
+            override fun eglCreateWindowSurface(
+                config: EGLConfig,
+                surface: Surface,
+                configAttributes: EglConfigAttributes?,
+            ): EGLSurface =
+                EGL14.eglCreateWindowSurface(
+                    getDefaultDisplay(),
+                    config,
+                    surface,
+                    configAttributes?.attrs ?: DefaultWindowSurfaceConfig.attrs,
+                    0
+                )
+
+            override fun eglSwapBuffers(surface: EGLSurface): Boolean =
+                EGL14.eglSwapBuffers(getDefaultDisplay(), surface)
+
+            override fun eglQuerySurface(
+                surface: EGLSurface,
+                attribute: Int,
+                result: IntArray,
+                offset: Int
+            ): Boolean =
+                EGL14.eglQuerySurface(getDefaultDisplay(), surface, attribute, result, offset)
+
+            override fun eglDestroySurface(surface: EGLSurface) =
+                EGL14.eglDestroySurface(getDefaultDisplay(), surface)
+
+            override fun eglMakeCurrent(
+                context: EGLContext,
+                drawSurface: EGLSurface,
+                readSurface: EGLSurface
+            ): Boolean =
+                EGL14.eglMakeCurrent(
+                    getDefaultDisplay(),
+                    drawSurface,
+                    readSurface,
+                    context
+                )
+
+            override fun loadConfig(configAttributes: EglConfigAttributes): EGLConfig? {
+                val configs = arrayOfNulls<EGLConfig?>(1)
+                return if (EGL14.eglChooseConfig(
+                    getDefaultDisplay(),
+                    configAttributes.attrs,
+                    0,
+                    configs,
+                    0,
+                    1,
+                    intArrayOf(1),
+                    0
+                )) {
+                    configs[0]
+                } else {
+                    null
+                }
+            }
+
+            override fun eglCreateContext(config: EGLConfig): EGLContext {
+                return EGL14.eglCreateContext(
+                    getDefaultDisplay(),
+                    config,
+                    EGL14.EGL_NO_CONTEXT, // not creating from a shared context
+                    contextAttributes,
+                    0
+                )
+            }
+
+            override fun eglDestroyContext(eglContext: EGLContext) {
+                if (!EGL14.eglDestroyContext(getDefaultDisplay(), eglContext)) {
+                    throw EglException(EGL14.eglGetError(), "Unable to destroy EGLContext")
+                }
+            }
+
+            override fun eglGetError(): Int = EGL14.eglGetError()
+
+            private fun getDefaultDisplay() = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY)
+
+            /**
+             * EglConfigAttribute that provides the default attributes for an EGL window surface
+             */
+            private val DefaultWindowSurfaceConfig = EglConfigAttributes {}
+        }
+
+        /**
+         * Return a string representation of the corresponding EGL status code.
+         * If the provided error value is not an EGL status code, the hex representation
+         * is returned instead
+         */
+        @JvmStatic
+        fun getStatusString(error: Int): String =
+            when (error) {
+                EGL14.EGL_SUCCESS -> "EGL_SUCCESS"
+                EGL14.EGL_NOT_INITIALIZED -> "EGL_NOT_INITIALIZED"
+                EGL14.EGL_BAD_ACCESS -> "EGL_BAD_ACCESS"
+                EGL14.EGL_BAD_ALLOC -> "EGL_BAD_ALLOC"
+                EGL14.EGL_BAD_ATTRIBUTE -> "EGL_BAD_ATTRIBUTE"
+                EGL14.EGL_BAD_CONFIG -> "EGL_BAD_CONFIG"
+                EGL14.EGL_BAD_CONTEXT -> "EGL_BAD_CONTEXT"
+                EGL14.EGL_BAD_CURRENT_SURFACE -> "EGL_BAD_CURRENT_SURFACE"
+                EGL14.EGL_BAD_DISPLAY -> "EGL_BAD_DISPLAY"
+                EGL14.EGL_BAD_MATCH -> "EGL_BAD_MATCH"
+                EGL14.EGL_BAD_NATIVE_PIXMAP -> "EGL_BAD_NATIVE_PIXMAP"
+                EGL14.EGL_BAD_NATIVE_WINDOW -> "EGL_BAD_NATIVE_WINDOW"
+                EGL14.EGL_BAD_PARAMETER -> "EGL_BAD_PARAMETER"
+                EGL14.EGL_BAD_SURFACE -> "EGL_BAD_SURFACE"
+                EGL14.EGL_CONTEXT_LOST -> "EGL_CONTEXT_LOST"
+                else -> Integer.toHexString(error)
+            }
+    }
+}
+
+/**
+ * Exception class for reporting errors with EGL
+ *
+ * @param error Error code reported via eglGetError
+ * @param msg Optional message describing the exception being thrown
+ */
+class EglException(val error: Int, val msg: String = "") : RuntimeException() {
+
+    override val message: String
+        get() = "Error: ${EglSpec.getStatusString(error)}, $msg"
+}
+
+/**
+ * Identifier for the current EGL implementation
+ *
+ * @param major Major version of the EGL implementation
+ * @param minor Minor version of the EGL implementation
+ */
+data class EglVersion(
+    val major: Int,
+    val minor: Int
+) {
+
+    override fun toString(): String {
+        return "EGL version $major.$minor"
+    }
+
+    companion object {
+        /**
+         * Constant that represents version 1.4 of the EGL spec
+         */
+        @JvmField
+        val V14 = EglVersion(1, 4)
+
+        /**
+         * Constant that represents version 1.5 of the EGL spec
+         */
+        @JvmField
+        val V15 = EglVersion(1, 5)
+
+        /**
+         * Sentinel EglVersion value returned in error situations
+         */
+        @JvmField
+        val Unknown = EglVersion(-1, -1)
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlCompat.kt b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlCompat.kt
new file mode 100644
index 0000000..2a4ac79
--- /dev/null
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlCompat.kt
@@ -0,0 +1,175 @@
+/*
+ * 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.
+ * 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.graphics.surface
+
+import android.os.Build
+import android.view.Surface
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.Q)
+class SurfaceControlCompat internal constructor(
+    surface: Surface? = null,
+    surfaceControl: SurfaceControlCompat? = null,
+    debugName: String
+) {
+    private var mNativeSurfaceControl: Long = 0
+
+    init {
+        if (surface != null) {
+            mNativeSurfaceControl = nCreateFromWindow(surface, debugName)
+        } else if (surfaceControl != null) {
+            mNativeSurfaceControl = nCreate(surfaceControl.mNativeSurfaceControl, debugName)
+        }
+
+        if (mNativeSurfaceControl == 0L) {
+            throw IllegalArgumentException()
+        }
+    }
+
+    /**
+     * Callback interface for usage with addTransactionCompletedListener
+     */
+    interface TransactionCompletedListener {
+        fun onComplete(latchTime: Long, presentTime: Long)
+    }
+
+    open class Transaction() {
+        private var mNativeSurfaceTransaction: Long
+
+        init {
+            mNativeSurfaceTransaction = nTransactionCreate()
+            if (mNativeSurfaceTransaction == 0L) {
+                throw java.lang.IllegalArgumentException()
+            }
+        }
+
+        /**
+         * Commits the updates accumulated in \a transaction.
+         *
+         * This is the equivalent of ASurfaceTransaction_apply.
+         *
+         * Note that the transaction is guaranteed to be applied atomically. The
+         * transactions which are applied on the same thread are als guaranteed to be applied
+         * in order.
+         */
+        fun commit() {
+            nTransactionApply(mNativeSurfaceTransaction)
+        }
+
+        // Suppression of PairedRegistration below is in order to match existing
+        // framework implementation of no remove method for listeners
+
+        /**
+         * Sets the callback that is invoked once the updates from this transaction are
+         * presented.
+         */
+        @Suppress("PairedRegistration")
+        fun addTransactionCompletedListener(listener: TransactionCompletedListener) {
+            nTransactionSetOnComplete(mNativeSurfaceTransaction, listener)
+        }
+
+        fun delete() {
+            if (mNativeSurfaceTransaction != 0L) {
+                nTransactionDelete(mNativeSurfaceTransaction)
+            }
+            mNativeSurfaceTransaction = 0L
+        }
+
+        fun finalize() {
+            delete()
+        }
+
+        private external fun nTransactionCreate(): Long
+        private external fun nTransactionDelete(surfaceTransaction: Long)
+        private external fun nTransactionApply(surfaceTransaction: Long)
+        private external fun nTransactionSetOnComplete(
+            surfaceTransaction: Long,
+            listener: TransactionCompletedListener
+        )
+
+        companion object {
+            init {
+                System.loadLibrary("graphics-core")
+            }
+        }
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (other == this) {
+            return true
+        }
+        if ((other == null) or
+            (other?.javaClass != SurfaceControlCompat::class.java)
+        ) {
+            return false
+        }
+
+        other as SurfaceControlCompat
+        if (other.mNativeSurfaceControl == this.mNativeSurfaceControl) {
+            return true
+        }
+
+        return false
+    }
+
+    override fun hashCode(): Int {
+        return mNativeSurfaceControl.hashCode()
+    }
+
+    protected fun finalize() {
+        nRelease(mNativeSurfaceControl)
+        mNativeSurfaceControl = 0
+    }
+
+    /**
+     * Builder class for SurfaceControlCompat.
+     *
+     * Requires a parent surface. Debug name is default empty string.
+     */
+    class Builder private constructor(surface: Surface?, surfaceControl: SurfaceControlCompat?) {
+        private var mSurface: Surface? = surface
+        private var mSurfaceControl: SurfaceControlCompat? = surfaceControl
+        private var mDebugName: String = ""
+
+        constructor(surface: Surface) : this(surface, null) {}
+
+        constructor(surfaceControl: SurfaceControlCompat) : this(null, surfaceControl) {}
+
+        @Suppress("MissingGetterMatchingBuilder")
+        fun setDebugName(debugName: String): Builder {
+            mDebugName = debugName
+            return this
+        }
+
+        /**
+         * Builds the SurfaceControlCompat object
+         */
+        fun build(): SurfaceControlCompat {
+            return SurfaceControlCompat(mSurface, mSurfaceControl, mDebugName)
+        }
+    }
+
+    private external fun nCreate(surfaceControl: Long, debugName: String): Long
+    private external fun nCreateFromWindow(surface: Surface, debugName: String): Long
+    private external fun nRelease(surfaceControl: Long)
+
+    companion object {
+        init {
+            System.loadLibrary("graphics-core")
+        }
+    }
+}
\ No newline at end of file
diff --git a/health/health-connect-client/src/main/java/androidx/health/connect/client/permission/HealthDataRequestPermissions.kt b/health/health-connect-client/src/main/java/androidx/health/connect/client/permission/HealthDataRequestPermissions.kt
index a1e1d2f..6746251 100644
--- a/health/health-connect-client/src/main/java/androidx/health/connect/client/permission/HealthDataRequestPermissions.kt
+++ b/health/health-connect-client/src/main/java/androidx/health/connect/client/permission/HealthDataRequestPermissions.kt
@@ -54,6 +54,7 @@
         }
     }
 
+    @Suppress("DEPRECATION")
     override fun parseResult(resultCode: Int, intent: Intent?): Set<Permission> {
         return intent
             ?.getParcelableArrayListExtra<ProtoPermission>(KEY_GRANTED_PERMISSIONS_JETPACK)
diff --git a/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/HeifWriterTest.java b/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/HeifWriterTest.java
index fd65713..af40a5a 100644
--- a/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/HeifWriterTest.java
+++ b/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/HeifWriterTest.java
@@ -459,7 +459,11 @@
                 }
                 mWidth = mBitmaps[0].getWidth();
                 mHeight = mBitmaps[0].getHeight();
-                retriever.release();
+                try {
+                    retriever.release();
+                } catch (IOException e) {
+                    // Nothing we can  do about it.
+                }
             }
 
             private void cleanupStaleOutputs() {
@@ -702,7 +706,11 @@
         assertEquals("Wrong primary index", primary,
                 Integer.parseInt(retriever.extractMetadata(
                         MediaMetadataRetriever.METADATA_KEY_IMAGE_PRIMARY)));
-        retriever.release();
+        try {
+            retriever.release();
+        } catch (IOException e) {
+            // Nothing we can  do about it.
+        }
 
         if (useGrid) {
             MediaExtractor extractor = new MediaExtractor();
diff --git a/libraryversions.toml b/libraryversions.toml
index db1a2ae..9b0e71e 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -1,9 +1,9 @@
 [versions]
-ACTIVITY = "1.5.0-rc01"
+ACTIVITY = "1.6.0-alpha03"
 ADS_IDENTIFIER = "1.0.0-alpha05"
 ANNOTATION = "1.4.0-alpha03"
 ANNOTATION_EXPERIMENTAL = "1.3.0-alpha01"
-APPCOMPAT = "1.5.0-alpha02"
+APPCOMPAT = "1.6.0-alpha03"
 APPSEARCH = "1.0.0-alpha05"
 ARCH_CORE = "2.2.0-alpha01"
 ASYNCLAYOUTINFLATER = "1.1.0-alpha01"
@@ -22,7 +22,7 @@
 COMPOSE_MATERIAL3 = "1.0.0-alpha11"
 CONTENTPAGER = "1.1.0-alpha01"
 COORDINATORLAYOUT = "1.3.0-alpha01"
-CORE = "1.8.0-rc01"
+CORE = "1.9.0-alpha03"
 CORE_ANIMATION = "1.0.0-beta02"
 CORE_ANIMATION_TESTING = "1.0.0-beta01"
 CORE_APPDIGEST = "1.0.0-alpha01"
@@ -50,6 +50,7 @@
 FUTURES = "1.2.0-alpha01"
 GLANCE = "1.0.0-alpha04"
 GLANCE_TEMPLATE = "1.0.0-alpha01"
+GRAPHICS = "1.0.0-alpha01"
 GRIDLAYOUT = "1.1.0-alpha01"
 HEALTH_CONNECT_CLIENT = "1.0.0-alpha01"
 HEALTH_SERVICES_CLIENT = "1.0.0-alpha04"
@@ -130,7 +131,7 @@
 WINDOW = "1.1.0-alpha02"
 WINDOW_EXTENSIONS = "1.1.0-alpha01"
 WINDOW_SIDECAR = "1.0.0-rc01"
-WORK = "2.8.0-alpha02"
+WORK = "2.8.0-alpha03"
 
 [groups]
 ACTIVITY = { group = "androidx.activity", atomicGroupVersion = "versions.ACTIVITY" }
@@ -177,6 +178,7 @@
 FRAGMENT = { group = "androidx.fragment", atomicGroupVersion = "versions.FRAGMENT" }
 GLANCE = { group = "androidx.glance", atomicGroupVersion = "versions.GLANCE" }
 GLANCE_TEMPLATE = { group = "androidx.template", atomicGroupVersion = "versions.GLANCE_TEMPLATE" }
+GRAPHICS = { group = "androidx.graphics", atomicGroupVersion = "versions.GRAPHICS" }
 GRIDLAYOUT = { group = "androidx.gridlayout", atomicGroupVersion = "versions.GRIDLAYOUT" }
 HEALTH = { group = "androidx.health" }
 HEIFWRITER = { group = "androidx.heifwriter", atomicGroupVersion = "versions.HEIFWRITER" }
diff --git a/lifecycle/lifecycle-livedata-ktx/api/2.5.0-beta01.txt b/lifecycle/lifecycle-livedata-ktx/api/2.5.0-beta01.txt
index 7bf189f..784f04e 100644
--- a/lifecycle/lifecycle-livedata-ktx/api/2.5.0-beta01.txt
+++ b/lifecycle/lifecycle-livedata-ktx/api/2.5.0-beta01.txt
@@ -15,8 +15,8 @@
   }
 
   public interface LiveDataScope<T> {
-    method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle>);
+    method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public suspend Object? emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle> p);
     method public T? getLatestValue();
     property public abstract T? latestValue;
   }
diff --git a/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.5.0-beta01.txt b/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.5.0-beta01.txt
index b542f27..7b099da 100644
--- a/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.5.0-beta01.txt
+++ b/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.5.0-beta01.txt
@@ -15,8 +15,8 @@
   }
 
   public interface LiveDataScope<T> {
-    method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle>);
+    method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public suspend Object? emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle> p);
     method public T? getLatestValue();
     property public abstract T? latestValue;
   }
diff --git a/lifecycle/lifecycle-livedata-ktx/api/restricted_2.5.0-beta01.txt b/lifecycle/lifecycle-livedata-ktx/api/restricted_2.5.0-beta01.txt
index 7bf189f..784f04e 100644
--- a/lifecycle/lifecycle-livedata-ktx/api/restricted_2.5.0-beta01.txt
+++ b/lifecycle/lifecycle-livedata-ktx/api/restricted_2.5.0-beta01.txt
@@ -15,8 +15,8 @@
   }
 
   public interface LiveDataScope<T> {
-    method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle>);
+    method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public suspend Object? emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle> p);
     method public T? getLatestValue();
     property public abstract T? latestValue;
   }
diff --git a/lifecycle/lifecycle-runtime-ktx/api/2.5.0-beta01.txt b/lifecycle/lifecycle-runtime-ktx/api/2.5.0-beta01.txt
index 46720fe..13b58cd 100644
--- a/lifecycle/lifecycle-runtime-ktx/api/2.5.0-beta01.txt
+++ b/lifecycle/lifecycle-runtime-ktx/api/2.5.0-beta01.txt
@@ -24,18 +24,18 @@
   }
 
   public final class PausingDispatcherKt {
-    method public static suspend <T> Object? whenCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State minState, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method public static suspend <T> Object? whenCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State minState, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
   }
 
   public final class RepeatOnLifecycleKt {
-    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
   }
 
   public final class ViewKt {
@@ -43,14 +43,14 @@
   }
 
   public final class WithLifecycleStateKt {
-    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
   }
 
 }
diff --git a/lifecycle/lifecycle-runtime-ktx/api/public_plus_experimental_2.5.0-beta01.txt b/lifecycle/lifecycle-runtime-ktx/api/public_plus_experimental_2.5.0-beta01.txt
index 46720fe..13b58cd 100644
--- a/lifecycle/lifecycle-runtime-ktx/api/public_plus_experimental_2.5.0-beta01.txt
+++ b/lifecycle/lifecycle-runtime-ktx/api/public_plus_experimental_2.5.0-beta01.txt
@@ -24,18 +24,18 @@
   }
 
   public final class PausingDispatcherKt {
-    method public static suspend <T> Object? whenCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State minState, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method public static suspend <T> Object? whenCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State minState, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
   }
 
   public final class RepeatOnLifecycleKt {
-    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
   }
 
   public final class ViewKt {
@@ -43,14 +43,14 @@
   }
 
   public final class WithLifecycleStateKt {
-    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
   }
 
 }
diff --git a/lifecycle/lifecycle-runtime-ktx/api/restricted_2.5.0-beta01.txt b/lifecycle/lifecycle-runtime-ktx/api/restricted_2.5.0-beta01.txt
index 28a306d..f721a9e 100644
--- a/lifecycle/lifecycle-runtime-ktx/api/restricted_2.5.0-beta01.txt
+++ b/lifecycle/lifecycle-runtime-ktx/api/restricted_2.5.0-beta01.txt
@@ -24,18 +24,18 @@
   }
 
   public final class PausingDispatcherKt {
-    method public static suspend <T> Object? whenCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
-    method public static suspend <T> Object? whenStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State minState, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method public static suspend <T> Object? whenCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
+    method public static suspend <T> Object? whenStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State minState, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T> p);
   }
 
   public final class RepeatOnLifecycleKt {
-    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
   }
 
   public final class ViewKt {
@@ -43,16 +43,16 @@
   }
 
   public final class WithLifecycleStateKt {
-    method @kotlin.PublishedApi internal static suspend <R> Object? suspendWithStateAtLeastUnchecked(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, boolean dispatchNeeded, kotlinx.coroutines.CoroutineDispatcher lifecycleDispatcher, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
-    method @kotlin.PublishedApi internal static suspend inline <R> Object? withStateAtLeastUnchecked(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method @kotlin.PublishedApi internal static suspend <R> Object? suspendWithStateAtLeastUnchecked(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, boolean dispatchNeeded, kotlinx.coroutines.CoroutineDispatcher lifecycleDispatcher, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
+    method @kotlin.PublishedApi internal static suspend inline <R> Object? withStateAtLeastUnchecked(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R> p);
   }
 
 }
diff --git a/lifecycle/lifecycle-runtime-testing/api/2.5.0-beta01.txt b/lifecycle/lifecycle-runtime-testing/api/2.5.0-beta01.txt
index dc2274c..8209a73 100644
--- a/lifecycle/lifecycle-runtime-testing/api/2.5.0-beta01.txt
+++ b/lifecycle/lifecycle-runtime-testing/api/2.5.0-beta01.txt
@@ -9,7 +9,7 @@
     method public androidx.lifecycle.LifecycleRegistry getLifecycle();
     method public int getObserverCount();
     method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event event);
-    method public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    method public void setCurrentState(androidx.lifecycle.Lifecycle.State value);
     property public final androidx.lifecycle.Lifecycle.State currentState;
     property public final int observerCount;
   }
diff --git a/lifecycle/lifecycle-runtime-testing/api/public_plus_experimental_2.5.0-beta01.txt b/lifecycle/lifecycle-runtime-testing/api/public_plus_experimental_2.5.0-beta01.txt
index dc2274c..8209a73 100644
--- a/lifecycle/lifecycle-runtime-testing/api/public_plus_experimental_2.5.0-beta01.txt
+++ b/lifecycle/lifecycle-runtime-testing/api/public_plus_experimental_2.5.0-beta01.txt
@@ -9,7 +9,7 @@
     method public androidx.lifecycle.LifecycleRegistry getLifecycle();
     method public int getObserverCount();
     method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event event);
-    method public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    method public void setCurrentState(androidx.lifecycle.Lifecycle.State value);
     property public final androidx.lifecycle.Lifecycle.State currentState;
     property public final int observerCount;
   }
diff --git a/lifecycle/lifecycle-runtime-testing/api/restricted_2.5.0-beta01.txt b/lifecycle/lifecycle-runtime-testing/api/restricted_2.5.0-beta01.txt
index dc2274c..8209a73 100644
--- a/lifecycle/lifecycle-runtime-testing/api/restricted_2.5.0-beta01.txt
+++ b/lifecycle/lifecycle-runtime-testing/api/restricted_2.5.0-beta01.txt
@@ -9,7 +9,7 @@
     method public androidx.lifecycle.LifecycleRegistry getLifecycle();
     method public int getObserverCount();
     method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event event);
-    method public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    method public void setCurrentState(androidx.lifecycle.Lifecycle.State value);
     property public final androidx.lifecycle.Lifecycle.State currentState;
     property public final int observerCount;
   }
diff --git a/lifecycle/lifecycle-service/src/androidTest/java/androidx/lifecycle/ServiceLifecycleTest.java b/lifecycle/lifecycle-service/src/androidTest/java/androidx/lifecycle/ServiceLifecycleTest.java
index 1cab987..04055db 100644
--- a/lifecycle/lifecycle-service/src/androidTest/java/androidx/lifecycle/ServiceLifecycleTest.java
+++ b/lifecycle/lifecycle-service/src/androidTest/java/androidx/lifecycle/ServiceLifecycleTest.java
@@ -52,6 +52,7 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
+@SuppressWarnings("deprecation")
 @MediumTest
 @RunWith(AndroidJUnit4.class)
 public class ServiceLifecycleTest {
diff --git a/lifecycle/lifecycle-viewmodel-compose/api/public_plus_experimental_2.5.0-beta01.txt b/lifecycle/lifecycle-viewmodel-compose/api/public_plus_experimental_2.5.0-beta01.txt
index 8a4ed64..55cd478 100644
--- a/lifecycle/lifecycle-viewmodel-compose/api/public_plus_experimental_2.5.0-beta01.txt
+++ b/lifecycle/lifecycle-viewmodel-compose/api/public_plus_experimental_2.5.0-beta01.txt
@@ -13,9 +13,6 @@
 
   public final class SavedStateHandleSaverKt {
     method @androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi public static <T> T saveable(androidx.lifecycle.SavedStateHandle, String key, optional androidx.compose.runtime.saveable.Saver<T,?> saver, kotlin.jvm.functions.Function0<? extends T> init);
-    method @androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi public static <T> androidx.compose.runtime.MutableState<T> saveable(androidx.lifecycle.SavedStateHandle, String key, androidx.compose.runtime.saveable.Saver<T,?> stateSaver, kotlin.jvm.functions.Function0<? extends androidx.compose.runtime.MutableState<T>> init);
-    method @androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi public static <T> kotlin.properties.PropertyDelegateProvider<java.lang.Object,kotlin.properties.ReadOnlyProperty<java.lang.Object,T>> saveable(androidx.lifecycle.SavedStateHandle, optional androidx.compose.runtime.saveable.Saver<T,?> saver, kotlin.jvm.functions.Function0<? extends T> init);
-    method @androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi public static <T, M extends androidx.compose.runtime.MutableState<T>> kotlin.properties.PropertyDelegateProvider<java.lang.Object,kotlin.properties.ReadWriteProperty<java.lang.Object,T>> saveableMutableState(androidx.lifecycle.SavedStateHandle, optional androidx.compose.runtime.saveable.Saver<T,?> stateSaver, kotlin.jvm.functions.Function0<? extends M> init);
   }
 
   public final class ViewModelKt {
diff --git a/media/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java b/media/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
index 16acd88..717e9c1 100644
--- a/media/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
+++ b/media/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
@@ -1185,6 +1185,7 @@
          * @param mediaButtonEvent The media button event intent.
          * @return True if the event was handled, false otherwise.
          */
+        @SuppressWarnings("deprecation")
         public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
             if (android.os.Build.VERSION.SDK_INT >= 27) {
                 // Double tap of play/pause as skipping to next is already handled by framework,
diff --git a/media/media/src/main/java/androidx/media/session/MediaButtonReceiver.java b/media/media/src/main/java/androidx/media/session/MediaButtonReceiver.java
index 10d515c..1b26d16 100644
--- a/media/media/src/main/java/androidx/media/session/MediaButtonReceiver.java
+++ b/media/media/src/main/java/androidx/media/session/MediaButtonReceiver.java
@@ -150,6 +150,7 @@
             mMediaBrowser = mediaBrowser;
         }
 
+        @SuppressWarnings("deprecation")
         @Override
         public void onConnected() {
             MediaControllerCompat mediaController = new MediaControllerCompat(mContext,
@@ -186,6 +187,7 @@
      * @param intent The intent to parse.
      * @return The extracted {@link KeyEvent} if found, or null.
      */
+    @SuppressWarnings("deprecation")
     public static KeyEvent handleIntent(MediaSessionCompat mediaSessionCompat, Intent intent) {
         if (mediaSessionCompat == null || intent == null
                 || !Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())
diff --git a/media2/integration-tests/testapp/src/main/java/androidx/media2/integration/testapp/VideoSessionService.java b/media2/integration-tests/testapp/src/main/java/androidx/media2/integration/testapp/VideoSessionService.java
index 8ff807d..f2df815 100644
--- a/media2/integration-tests/testapp/src/main/java/androidx/media2/integration/testapp/VideoSessionService.java
+++ b/media2/integration-tests/testapp/src/main/java/androidx/media2/integration/testapp/VideoSessionService.java
@@ -39,6 +39,7 @@
 
 import com.google.common.util.concurrent.ListenableFuture;
 
+import java.io.IOException;
 import java.lang.ref.WeakReference;
 import java.util.List;
 import java.util.concurrent.Executor;
@@ -195,7 +196,11 @@
             Bitmap musicAlbumBitmap = extractAlbumArt(retriever);
 
             if (retriever != null) {
-                retriever.release();
+                try {
+                    retriever.release();
+                } catch (IOException e) {
+                    // Nothing we can do about that...
+                }
             }
 
             MediaMetadata metadata = mediaItem.getMetadata();
diff --git a/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer2Test.java b/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer2Test.java
index d2b5aa5..d694aa5 100644
--- a/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer2Test.java
+++ b/media2/media2-player/src/androidTest/java/androidx/media2/player/MediaPlayer2Test.java
@@ -826,7 +826,11 @@
         retriever.setDataSource(file);
         String rotation = retriever.extractMetadata(
                 MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
-        retriever.release();
+        try {
+            retriever.release();
+        } catch (IOException e) {
+            // Nothing we can  do about it.
+        }
         retriever = null;
         assertNotNull(rotation);
         assertEquals(Integer.parseInt(rotation), angle);
diff --git a/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionImplBase.java b/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionImplBase.java
index 34f5ad0..27ec402 100644
--- a/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionImplBase.java
+++ b/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionImplBase.java
@@ -1672,6 +1672,7 @@
 
     @SuppressWarnings("WeakerAccess") /* synthetic access */
     final class MediaButtonReceiver extends BroadcastReceiver {
+        @SuppressWarnings("deprecation")
         @Override
         public void onReceive(Context context, Intent intent) {
             if (!Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
diff --git a/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionServiceImplBase.java b/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionServiceImplBase.java
index 5dc5374..9515408 100644
--- a/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionServiceImplBase.java
+++ b/media2/media2-session/src/main/java/androidx/media2/session/MediaSessionServiceImplBase.java
@@ -150,6 +150,7 @@
         }
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
         if (intent == null || intent.getAction() == null) {
diff --git a/media2/media2-session/version-compat-tests/previous/client/src/androidTest/java/androidx/media2/test/client/tests/MediaControllerTest.java b/media2/media2-session/version-compat-tests/previous/client/src/androidTest/java/androidx/media2/test/client/tests/MediaControllerTest.java
index 1063ae5..8c81f3c 100644
--- a/media2/media2-session/version-compat-tests/previous/client/src/androidTest/java/androidx/media2/test/client/tests/MediaControllerTest.java
+++ b/media2/media2-session/version-compat-tests/previous/client/src/androidTest/java/androidx/media2/test/client/tests/MediaControllerTest.java
@@ -39,7 +39,6 @@
 import android.util.Log;
 
 import androidx.annotation.NonNull;
-import androidx.core.os.BuildCompat;
 import androidx.core.util.Pair;
 import androidx.media.AudioAttributesCompat;
 import androidx.media2.common.MediaItem;
@@ -153,7 +152,7 @@
             // TODO(b/220842943): Re-enable for T and beyond once the version of media2-session
             // used in version-compat-tests/previous/client/build.gradle is one that includes
             // https://r.android.com/1950077.
-            if (!BuildCompat.isAtLeastT()) {
+            if (Build.VERSION.SDK_INT < 33) {
                 fail("custom parcelables shouldn't be allowed for connectionHints");
             }
         } catch (IllegalArgumentException e) {
diff --git a/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSessionTest.java b/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSessionTest.java
index 00eaef1..eb4ebe5 100644
--- a/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSessionTest.java
+++ b/media2/media2-session/version-compat-tests/previous/service/src/androidTest/java/androidx/media2/test/service/tests/MediaSessionTest.java
@@ -29,7 +29,6 @@
 import android.util.Log;
 
 import androidx.annotation.NonNull;
-import androidx.core.os.BuildCompat;
 import androidx.media2.common.MediaItem;
 import androidx.media2.common.MediaMetadata;
 import androidx.media2.common.SessionPlayer;
@@ -128,7 +127,7 @@
             // TODO(b/220842943): Re-enable for T and beyond once the version of media2-session
             // used in version-compat-tests/previous/service/build.gradle is one that includes
             // https://r.android.com/1950077.
-            if (!BuildCompat.isAtLeastT()) {
+            if (Build.VERSION.SDK_INT < 33) {
                 fail("custom parcelables shouldn't be allowed for extras");
             }
         } catch (IllegalArgumentException e) {
diff --git a/navigation/navigation-common-ktx/api/2.5.0-beta01.txt b/navigation/navigation-common-ktx/api/2.5.0-beta01.txt
deleted file mode 100644
index e6f50d0..0000000
--- a/navigation/navigation-common-ktx/api/2.5.0-beta01.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 4.0
diff --git a/navigation/navigation-common-ktx/api/public_plus_experimental_2.5.0-beta01.txt b/navigation/navigation-common-ktx/api/public_plus_experimental_2.5.0-beta01.txt
deleted file mode 100644
index e6f50d0..0000000
--- a/navigation/navigation-common-ktx/api/public_plus_experimental_2.5.0-beta01.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 4.0
diff --git a/navigation/navigation-common-ktx/api/res-2.5.0-beta01.txt b/navigation/navigation-common-ktx/api/res-2.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/navigation/navigation-common-ktx/api/res-2.5.0-beta01.txt
+++ /dev/null
diff --git a/navigation/navigation-common-ktx/api/restricted_2.5.0-beta01.txt b/navigation/navigation-common-ktx/api/restricted_2.5.0-beta01.txt
deleted file mode 100644
index e6f50d0..0000000
--- a/navigation/navigation-common-ktx/api/restricted_2.5.0-beta01.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 4.0
diff --git a/navigation/navigation-common/api/2.5.0-beta01.txt b/navigation/navigation-common/api/2.5.0-beta01.txt
deleted file mode 100644
index fe9681f..0000000
--- a/navigation/navigation-common/api/2.5.0-beta01.txt
+++ /dev/null
@@ -1,522 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation {
-
-  public final class ActionOnlyNavDirections implements androidx.navigation.NavDirections {
-    ctor public ActionOnlyNavDirections(int actionId);
-    method public int component1();
-    method public androidx.navigation.ActionOnlyNavDirections copy(int actionId);
-    method public int getActionId();
-    method public android.os.Bundle getArguments();
-    property public int actionId;
-    property public android.os.Bundle arguments;
-  }
-
-  @androidx.navigation.NavOptionsDsl public final class AnimBuilder {
-    ctor public AnimBuilder();
-    method public int getEnter();
-    method public int getExit();
-    method public int getPopEnter();
-    method public int getPopExit();
-    method public void setEnter(int);
-    method public void setExit(int);
-    method public void setPopEnter(int);
-    method public void setPopExit(int);
-    property public final int enter;
-    property public final int exit;
-    property public final int popEnter;
-    property public final int popExit;
-  }
-
-  public interface FloatingWindow {
-  }
-
-  public final class NamedNavArgument {
-    method public operator String component1();
-    method public operator androidx.navigation.NavArgument component2();
-    method public androidx.navigation.NavArgument getArgument();
-    method public String getName();
-    property public final androidx.navigation.NavArgument argument;
-    property public final String name;
-  }
-
-  public final class NamedNavArgumentKt {
-    method public static androidx.navigation.NamedNavArgument navArgument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavAction {
-    ctor public NavAction(@IdRes int destinationId, optional androidx.navigation.NavOptions? navOptions, optional android.os.Bundle? defaultArguments);
-    ctor public NavAction(@IdRes int destinationId, optional androidx.navigation.NavOptions? navOptions);
-    ctor public NavAction(@IdRes int destinationId);
-    method public android.os.Bundle? getDefaultArguments();
-    method public int getDestinationId();
-    method public androidx.navigation.NavOptions? getNavOptions();
-    method public void setDefaultArguments(android.os.Bundle?);
-    method public void setNavOptions(androidx.navigation.NavOptions?);
-    property public final android.os.Bundle? defaultArguments;
-    property public final int destinationId;
-    property public final androidx.navigation.NavOptions? navOptions;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class NavActionBuilder {
-    ctor public NavActionBuilder();
-    method public java.util.Map<java.lang.String,java.lang.Object> getDefaultArguments();
-    method public int getDestinationId();
-    method public void navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
-    method public void setDestinationId(int);
-    property public final java.util.Map<java.lang.String,java.lang.Object> defaultArguments;
-    property public final int destinationId;
-  }
-
-  public interface NavArgs {
-  }
-
-  public final class NavArgsLazy<Args extends androidx.navigation.NavArgs> implements kotlin.Lazy<Args> {
-    ctor public NavArgsLazy(kotlin.reflect.KClass<Args> navArgsClass, kotlin.jvm.functions.Function0<android.os.Bundle> argumentProducer);
-    method public Args getValue();
-    method public boolean isInitialized();
-    property public Args value;
-  }
-
-  public final class NavArgsLazyKt {
-  }
-
-  public final class NavArgument {
-    method public Object? getDefaultValue();
-    method public androidx.navigation.NavType<java.lang.Object> getType();
-    method public boolean isDefaultValuePresent();
-    method public boolean isNullable();
-    property public final Object? defaultValue;
-    property public final boolean isDefaultValuePresent;
-    property public final boolean isNullable;
-    property public final androidx.navigation.NavType<java.lang.Object> type;
-  }
-
-  public static final class NavArgument.Builder {
-    ctor public NavArgument.Builder();
-    method public androidx.navigation.NavArgument build();
-    method public androidx.navigation.NavArgument.Builder setDefaultValue(Object? defaultValue);
-    method public androidx.navigation.NavArgument.Builder setIsNullable(boolean isNullable);
-    method public <T> androidx.navigation.NavArgument.Builder setType(androidx.navigation.NavType<T> type);
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class NavArgumentBuilder {
-    ctor public NavArgumentBuilder();
-    method public androidx.navigation.NavArgument build();
-    method public Object? getDefaultValue();
-    method public boolean getNullable();
-    method public androidx.navigation.NavType<?> getType();
-    method public void setDefaultValue(Object?);
-    method public void setNullable(boolean);
-    method public void setType(androidx.navigation.NavType<?>);
-    property public final Object? defaultValue;
-    property public final boolean nullable;
-    property public final androidx.navigation.NavType<?> type;
-  }
-
-  public final class NavBackStackEntry implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
-    method public android.os.Bundle? getArguments();
-    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
-    method public androidx.navigation.NavDestination getDestination();
-    method public String getId();
-    method public androidx.lifecycle.Lifecycle getLifecycle();
-    method public androidx.lifecycle.SavedStateHandle getSavedStateHandle();
-    method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
-    method public androidx.lifecycle.ViewModelStore getViewModelStore();
-    property public final android.os.Bundle? arguments;
-    property public final androidx.navigation.NavDestination destination;
-    property public final String id;
-    property public final androidx.lifecycle.SavedStateHandle savedStateHandle;
-    property public androidx.savedstate.SavedStateRegistry savedStateRegistry;
-  }
-
-  public final class NavDeepLink {
-    method public String? getAction();
-    method public String? getMimeType();
-    method public String? getUriPattern();
-    property public final String? action;
-    property public final String? mimeType;
-    property public final String? uriPattern;
-  }
-
-  public static final class NavDeepLink.Builder {
-    method public androidx.navigation.NavDeepLink build();
-    method public static androidx.navigation.NavDeepLink.Builder fromAction(String action);
-    method public static androidx.navigation.NavDeepLink.Builder fromMimeType(String mimeType);
-    method public static androidx.navigation.NavDeepLink.Builder fromUriPattern(String uriPattern);
-    method public androidx.navigation.NavDeepLink.Builder setAction(String action);
-    method public androidx.navigation.NavDeepLink.Builder setMimeType(String mimeType);
-    method public androidx.navigation.NavDeepLink.Builder setUriPattern(String uriPattern);
-  }
-
-  @kotlin.DslMarker public @interface NavDeepLinkDsl {
-  }
-
-  @androidx.navigation.NavDeepLinkDsl public final class NavDeepLinkDslBuilder {
-    ctor public NavDeepLinkDslBuilder();
-    method public String? getAction();
-    method public String? getMimeType();
-    method public String? getUriPattern();
-    method public void setAction(String?);
-    method public void setMimeType(String?);
-    method public void setUriPattern(String?);
-    property public final String? action;
-    property public final String? mimeType;
-    property public final String? uriPattern;
-  }
-
-  public final class NavDeepLinkDslBuilderKt {
-    method public static androidx.navigation.NavDeepLink navDeepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
-  }
-
-  public class NavDeepLinkRequest {
-    method public String? getAction();
-    method public String? getMimeType();
-    method public android.net.Uri? getUri();
-    property public String? action;
-    property public String? mimeType;
-    property public android.net.Uri? uri;
-  }
-
-  public static final class NavDeepLinkRequest.Builder {
-    method public androidx.navigation.NavDeepLinkRequest build();
-    method public static androidx.navigation.NavDeepLinkRequest.Builder fromAction(String action);
-    method public static androidx.navigation.NavDeepLinkRequest.Builder fromMimeType(String mimeType);
-    method public static androidx.navigation.NavDeepLinkRequest.Builder fromUri(android.net.Uri uri);
-    method public androidx.navigation.NavDeepLinkRequest.Builder setAction(String action);
-    method public androidx.navigation.NavDeepLinkRequest.Builder setMimeType(String mimeType);
-    method public androidx.navigation.NavDeepLinkRequest.Builder setUri(android.net.Uri uri);
-    field public static final androidx.navigation.NavDeepLinkRequest.Builder.Companion Companion;
-  }
-
-  public static final class NavDeepLinkRequest.Builder.Companion {
-    method public androidx.navigation.NavDeepLinkRequest.Builder fromAction(String action);
-    method public androidx.navigation.NavDeepLinkRequest.Builder fromMimeType(String mimeType);
-    method public androidx.navigation.NavDeepLinkRequest.Builder fromUri(android.net.Uri uri);
-  }
-
-  public class NavDestination {
-    ctor public NavDestination(String navigatorName);
-    ctor public NavDestination(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-    method public final void addArgument(String argumentName, androidx.navigation.NavArgument argument);
-    method public final void addDeepLink(String uriPattern);
-    method public final void addDeepLink(androidx.navigation.NavDeepLink navDeepLink);
-    method public final androidx.navigation.NavAction? getAction(@IdRes int id);
-    method public final java.util.Map<java.lang.String,androidx.navigation.NavArgument> getArguments();
-    method public static final kotlin.sequences.Sequence<androidx.navigation.NavDestination> getHierarchy(androidx.navigation.NavDestination);
-    method @IdRes public final int getId();
-    method public final CharSequence? getLabel();
-    method public final String getNavigatorName();
-    method public final androidx.navigation.NavGraph? getParent();
-    method public final String? getRoute();
-    method public boolean hasDeepLink(android.net.Uri deepLink);
-    method public boolean hasDeepLink(androidx.navigation.NavDeepLinkRequest deepLinkRequest);
-    method @CallSuper public void onInflate(android.content.Context context, android.util.AttributeSet attrs);
-    method protected static final <C> Class<? extends C> parseClassFromName(android.content.Context context, String name, Class<? extends C> expectedClassType);
-    method public final void putAction(@IdRes int actionId, @IdRes int destId);
-    method public final void putAction(@IdRes int actionId, androidx.navigation.NavAction action);
-    method public final void removeAction(@IdRes int actionId);
-    method public final void removeArgument(String argumentName);
-    method public final void setId(@IdRes int);
-    method public final void setLabel(CharSequence?);
-    method public final void setRoute(String?);
-    property public final java.util.Map<java.lang.String,androidx.navigation.NavArgument> arguments;
-    property @IdRes public final int id;
-    property public final CharSequence? label;
-    property public final String navigatorName;
-    property public final androidx.navigation.NavGraph? parent;
-    property public final String? route;
-    field public static final androidx.navigation.NavDestination.Companion Companion;
-  }
-
-  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface NavDestination.ClassType {
-    method public abstract kotlin.reflect.KClass<?> value();
-    property public abstract kotlin.reflect.KClass<?> value;
-  }
-
-  public static final class NavDestination.Companion {
-    method public kotlin.sequences.Sequence<androidx.navigation.NavDestination> getHierarchy(androidx.navigation.NavDestination);
-    method protected <C> Class<? extends C> parseClassFromName(android.content.Context context, String name, Class<? extends C> expectedClassType);
-  }
-
-  @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
-    ctor @Deprecated public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
-    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, String? route);
-    method @Deprecated public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
-    method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
-    method public D build();
-    method public final void deepLink(String uriPattern);
-    method public final void deepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> navDeepLink);
-    method public final int getId();
-    method public final CharSequence? getLabel();
-    method protected final androidx.navigation.Navigator<? extends D> getNavigator();
-    method public final String? getRoute();
-    method public final void setLabel(CharSequence?);
-    property public final int id;
-    property public final CharSequence? label;
-    property protected final androidx.navigation.Navigator<? extends D> navigator;
-    property public final String? route;
-  }
-
-  @kotlin.DslMarker public @interface NavDestinationDsl {
-  }
-
-  public interface NavDirections {
-    method @IdRes public int getActionId();
-    method public android.os.Bundle getArguments();
-    property @IdRes public abstract int actionId;
-    property public abstract android.os.Bundle arguments;
-  }
-
-  public class NavGraph extends androidx.navigation.NavDestination implements java.lang.Iterable<androidx.navigation.NavDestination> kotlin.jvm.internal.markers.KMappedMarker {
-    ctor public NavGraph(androidx.navigation.Navigator<? extends androidx.navigation.NavGraph> navGraphNavigator);
-    method public final void addAll(androidx.navigation.NavGraph other);
-    method public final void addDestination(androidx.navigation.NavDestination node);
-    method public final void addDestinations(java.util.Collection<? extends androidx.navigation.NavDestination> nodes);
-    method public final void addDestinations(androidx.navigation.NavDestination... nodes);
-    method public final void clear();
-    method public final androidx.navigation.NavDestination? findNode(@IdRes int resId);
-    method public final androidx.navigation.NavDestination? findNode(String? route);
-    method public static final androidx.navigation.NavDestination findStartDestination(androidx.navigation.NavGraph);
-    method @Deprecated @IdRes public final int getStartDestination();
-    method @IdRes public final int getStartDestinationId();
-    method public final String? getStartDestinationRoute();
-    method public final java.util.Iterator<androidx.navigation.NavDestination> iterator();
-    method public final void remove(androidx.navigation.NavDestination node);
-    method public final void setStartDestination(int startDestId);
-    method public final void setStartDestination(String startDestRoute);
-    property @IdRes public final int startDestinationId;
-    property public final String? startDestinationRoute;
-    field public static final androidx.navigation.NavGraph.Companion Companion;
-  }
-
-  public static final class NavGraph.Companion {
-    method public androidx.navigation.NavDestination findStartDestination(androidx.navigation.NavGraph);
-  }
-
-  @androidx.navigation.NavDestinationDsl public class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
-    ctor @Deprecated public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, String? route);
-    method public final void addDestination(androidx.navigation.NavDestination destination);
-    method public androidx.navigation.NavGraph build();
-    method public final <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
-    method public final androidx.navigation.NavigatorProvider getProvider();
-    method public final operator void unaryPlus(androidx.navigation.NavDestination);
-    property public final androidx.navigation.NavigatorProvider provider;
-  }
-
-  public final class NavGraphBuilderKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method @Deprecated public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavGraphKt {
-    method public static operator boolean contains(androidx.navigation.NavGraph, @IdRes int id);
-    method public static operator boolean contains(androidx.navigation.NavGraph, String route);
-    method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, @IdRes int id);
-    method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, String route);
-    method public static inline operator void minusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
-    method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
-    method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavGraph other);
-  }
-
-  @androidx.navigation.Navigator.Name("navigation") public class NavGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.NavGraph> {
-    ctor public NavGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider);
-    method public androidx.navigation.NavGraph createDestination();
-  }
-
-  public final class NavOptions {
-    method @AnimRes @AnimatorRes public int getEnterAnim();
-    method @AnimRes @AnimatorRes public int getExitAnim();
-    method @AnimRes @AnimatorRes public int getPopEnterAnim();
-    method @AnimRes @AnimatorRes public int getPopExitAnim();
-    method @Deprecated @IdRes public int getPopUpTo();
-    method @IdRes public int getPopUpToId();
-    method public String? getPopUpToRoute();
-    method public boolean isPopUpToInclusive();
-    method public boolean shouldLaunchSingleTop();
-    method public boolean shouldPopUpToSaveState();
-    method public boolean shouldRestoreState();
-    property @AnimRes @AnimatorRes public final int enterAnim;
-    property @AnimRes @AnimatorRes public final int exitAnim;
-    property @AnimRes @AnimatorRes public final int popEnterAnim;
-    property @AnimRes @AnimatorRes public final int popExitAnim;
-    property @IdRes public final int popUpToId;
-    property public final String? popUpToRoute;
-  }
-
-  public static final class NavOptions.Builder {
-    ctor public NavOptions.Builder();
-    method public androidx.navigation.NavOptions build();
-    method public androidx.navigation.NavOptions.Builder setEnterAnim(@AnimRes @AnimatorRes int enterAnim);
-    method public androidx.navigation.NavOptions.Builder setExitAnim(@AnimRes @AnimatorRes int exitAnim);
-    method public androidx.navigation.NavOptions.Builder setLaunchSingleTop(boolean singleTop);
-    method public androidx.navigation.NavOptions.Builder setPopEnterAnim(@AnimRes @AnimatorRes int popEnterAnim);
-    method public androidx.navigation.NavOptions.Builder setPopExitAnim(@AnimRes @AnimatorRes int popExitAnim);
-    method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int destinationId, boolean inclusive, optional boolean saveState);
-    method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int destinationId, boolean inclusive);
-    method public androidx.navigation.NavOptions.Builder setPopUpTo(String? route, boolean inclusive, optional boolean saveState);
-    method public androidx.navigation.NavOptions.Builder setPopUpTo(String? route, boolean inclusive);
-    method public androidx.navigation.NavOptions.Builder setRestoreState(boolean restoreState);
-  }
-
-  @androidx.navigation.NavOptionsDsl public final class NavOptionsBuilder {
-    ctor public NavOptionsBuilder();
-    method public void anim(kotlin.jvm.functions.Function1<? super androidx.navigation.AnimBuilder,kotlin.Unit> animBuilder);
-    method public boolean getLaunchSingleTop();
-    method @Deprecated public int getPopUpTo();
-    method public int getPopUpToId();
-    method public String? getPopUpToRoute();
-    method public boolean getRestoreState();
-    method public void popUpTo(@IdRes int id, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
-    method public void popUpTo(String route, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
-    method public void setLaunchSingleTop(boolean);
-    method @Deprecated public void setPopUpTo(int);
-    method public void setRestoreState(boolean);
-    property public final boolean launchSingleTop;
-    property @Deprecated public final int popUpTo;
-    property public final int popUpToId;
-    property public final String? popUpToRoute;
-    property public final boolean restoreState;
-  }
-
-  public final class NavOptionsBuilderKt {
-    method public static androidx.navigation.NavOptions navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
-  }
-
-  @kotlin.DslMarker public @interface NavOptionsDsl {
-  }
-
-  public abstract class NavType<T> {
-    ctor public NavType(boolean isNullableAllowed);
-    method public static androidx.navigation.NavType<?> fromArgType(String? type, String? packageName);
-    method public abstract operator T? get(android.os.Bundle bundle, String key);
-    method public String getName();
-    method public boolean isNullableAllowed();
-    method public abstract T! parseValue(String value);
-    method public abstract void put(android.os.Bundle bundle, String key, T? value);
-    property public boolean isNullableAllowed;
-    property public String name;
-    field public static final androidx.navigation.NavType<boolean[]> BoolArrayType;
-    field public static final androidx.navigation.NavType<java.lang.Boolean> BoolType;
-    field public static final androidx.navigation.NavType.Companion Companion;
-    field public static final androidx.navigation.NavType<float[]> FloatArrayType;
-    field public static final androidx.navigation.NavType<java.lang.Float> FloatType;
-    field public static final androidx.navigation.NavType<int[]> IntArrayType;
-    field public static final androidx.navigation.NavType<java.lang.Integer> IntType;
-    field public static final androidx.navigation.NavType<long[]> LongArrayType;
-    field public static final androidx.navigation.NavType<java.lang.Long> LongType;
-    field public static final androidx.navigation.NavType<java.lang.Integer> ReferenceType;
-    field public static final androidx.navigation.NavType<java.lang.String[]> StringArrayType;
-    field public static final androidx.navigation.NavType<java.lang.String> StringType;
-  }
-
-  public static final class NavType.Companion {
-    method public androidx.navigation.NavType<?> fromArgType(String? type, String? packageName);
-  }
-
-  public static final class NavType.EnumType<D extends java.lang.Enum<?>> extends androidx.navigation.NavType.SerializableType<D> {
-    ctor public NavType.EnumType(Class<D> type);
-    property public String name;
-  }
-
-  public static final class NavType.ParcelableArrayType<D extends android.os.Parcelable> extends androidx.navigation.NavType<D[]> {
-    ctor public NavType.ParcelableArrayType(Class<D> type);
-    method public D![]? get(android.os.Bundle bundle, String key);
-    method public D![] parseValue(String value);
-    method public void put(android.os.Bundle bundle, String key, D![]? value);
-    property public String name;
-  }
-
-  public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
-    ctor public NavType.ParcelableType(Class<D> type);
-    method public D? get(android.os.Bundle bundle, String key);
-    method public D! parseValue(String value);
-    method public void put(android.os.Bundle bundle, String key, D? value);
-    property public String name;
-  }
-
-  public static final class NavType.SerializableArrayType<D extends java.io.Serializable> extends androidx.navigation.NavType<D[]> {
-    ctor public NavType.SerializableArrayType(Class<D> type);
-    method public D![]? get(android.os.Bundle bundle, String key);
-    method public D![] parseValue(String value);
-    method public void put(android.os.Bundle bundle, String key, D![]? value);
-    property public String name;
-  }
-
-  public static class NavType.SerializableType<D extends java.io.Serializable> extends androidx.navigation.NavType<D> {
-    ctor public NavType.SerializableType(Class<D> type);
-    method public D? get(android.os.Bundle bundle, String key);
-    method public D parseValue(String value);
-    method public void put(android.os.Bundle bundle, String key, D value);
-    property public String name;
-  }
-
-  public abstract class Navigator<D extends androidx.navigation.NavDestination> {
-    ctor public Navigator();
-    method public abstract D createDestination();
-    method protected final androidx.navigation.NavigatorState getState();
-    method public final boolean isAttached();
-    method public void navigate(java.util.List<androidx.navigation.NavBackStackEntry> entries, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method public androidx.navigation.NavDestination? navigate(D destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method @CallSuper public void onAttach(androidx.navigation.NavigatorState state);
-    method public void onLaunchSingleTop(androidx.navigation.NavBackStackEntry backStackEntry);
-    method public void onRestoreState(android.os.Bundle savedState);
-    method public android.os.Bundle? onSaveState();
-    method public void popBackStack(androidx.navigation.NavBackStackEntry popUpTo, boolean savedState);
-    method public boolean popBackStack();
-    property public final boolean isAttached;
-    property protected final androidx.navigation.NavigatorState state;
-  }
-
-  public static interface Navigator.Extras {
-  }
-
-  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface Navigator.Name {
-    method public abstract String value();
-    property public abstract String value;
-  }
-
-  public class NavigatorProvider {
-    ctor public NavigatorProvider();
-    method public final androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? addNavigator(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-    method @CallSuper public androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? addNavigator(String name, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-    method public final <T extends androidx.navigation.Navigator<?>> T getNavigator(Class<T> navigatorClass);
-    method @CallSuper public <T extends androidx.navigation.Navigator<?>> T getNavigator(String name);
-  }
-
-  public final class NavigatorProviderKt {
-    method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, String name);
-    method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<T> clazz);
-    method public static inline operator void plusAssign(androidx.navigation.NavigatorProvider, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-    method public static inline operator androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? set(androidx.navigation.NavigatorProvider, String name, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-  }
-
-  public abstract class NavigatorState {
-    ctor public NavigatorState();
-    method public abstract androidx.navigation.NavBackStackEntry createBackStackEntry(androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
-    method public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getBackStack();
-    method public final kotlinx.coroutines.flow.StateFlow<java.util.Set<androidx.navigation.NavBackStackEntry>> getTransitionsInProgress();
-    method public void markTransitionComplete(androidx.navigation.NavBackStackEntry entry);
-    method @CallSuper public void onLaunchSingleTop(androidx.navigation.NavBackStackEntry backStackEntry);
-    method public void pop(androidx.navigation.NavBackStackEntry popUpTo, boolean saveState);
-    method public void popWithTransition(androidx.navigation.NavBackStackEntry popUpTo, boolean saveState);
-    method public void push(androidx.navigation.NavBackStackEntry backStackEntry);
-    method public void pushWithTransition(androidx.navigation.NavBackStackEntry backStackEntry);
-    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> backStack;
-    property public final kotlinx.coroutines.flow.StateFlow<java.util.Set<androidx.navigation.NavBackStackEntry>> transitionsInProgress;
-  }
-
-  @androidx.navigation.NavOptionsDsl public final class PopUpToBuilder {
-    ctor public PopUpToBuilder();
-    method public boolean getInclusive();
-    method public boolean getSaveState();
-    method public void setInclusive(boolean);
-    method public void setSaveState(boolean);
-    property public final boolean inclusive;
-    property public final boolean saveState;
-  }
-
-}
-
diff --git a/navigation/navigation-common/api/public_plus_experimental_2.5.0-beta01.txt b/navigation/navigation-common/api/public_plus_experimental_2.5.0-beta01.txt
deleted file mode 100644
index fe9681f..0000000
--- a/navigation/navigation-common/api/public_plus_experimental_2.5.0-beta01.txt
+++ /dev/null
@@ -1,522 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation {
-
-  public final class ActionOnlyNavDirections implements androidx.navigation.NavDirections {
-    ctor public ActionOnlyNavDirections(int actionId);
-    method public int component1();
-    method public androidx.navigation.ActionOnlyNavDirections copy(int actionId);
-    method public int getActionId();
-    method public android.os.Bundle getArguments();
-    property public int actionId;
-    property public android.os.Bundle arguments;
-  }
-
-  @androidx.navigation.NavOptionsDsl public final class AnimBuilder {
-    ctor public AnimBuilder();
-    method public int getEnter();
-    method public int getExit();
-    method public int getPopEnter();
-    method public int getPopExit();
-    method public void setEnter(int);
-    method public void setExit(int);
-    method public void setPopEnter(int);
-    method public void setPopExit(int);
-    property public final int enter;
-    property public final int exit;
-    property public final int popEnter;
-    property public final int popExit;
-  }
-
-  public interface FloatingWindow {
-  }
-
-  public final class NamedNavArgument {
-    method public operator String component1();
-    method public operator androidx.navigation.NavArgument component2();
-    method public androidx.navigation.NavArgument getArgument();
-    method public String getName();
-    property public final androidx.navigation.NavArgument argument;
-    property public final String name;
-  }
-
-  public final class NamedNavArgumentKt {
-    method public static androidx.navigation.NamedNavArgument navArgument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavAction {
-    ctor public NavAction(@IdRes int destinationId, optional androidx.navigation.NavOptions? navOptions, optional android.os.Bundle? defaultArguments);
-    ctor public NavAction(@IdRes int destinationId, optional androidx.navigation.NavOptions? navOptions);
-    ctor public NavAction(@IdRes int destinationId);
-    method public android.os.Bundle? getDefaultArguments();
-    method public int getDestinationId();
-    method public androidx.navigation.NavOptions? getNavOptions();
-    method public void setDefaultArguments(android.os.Bundle?);
-    method public void setNavOptions(androidx.navigation.NavOptions?);
-    property public final android.os.Bundle? defaultArguments;
-    property public final int destinationId;
-    property public final androidx.navigation.NavOptions? navOptions;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class NavActionBuilder {
-    ctor public NavActionBuilder();
-    method public java.util.Map<java.lang.String,java.lang.Object> getDefaultArguments();
-    method public int getDestinationId();
-    method public void navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
-    method public void setDestinationId(int);
-    property public final java.util.Map<java.lang.String,java.lang.Object> defaultArguments;
-    property public final int destinationId;
-  }
-
-  public interface NavArgs {
-  }
-
-  public final class NavArgsLazy<Args extends androidx.navigation.NavArgs> implements kotlin.Lazy<Args> {
-    ctor public NavArgsLazy(kotlin.reflect.KClass<Args> navArgsClass, kotlin.jvm.functions.Function0<android.os.Bundle> argumentProducer);
-    method public Args getValue();
-    method public boolean isInitialized();
-    property public Args value;
-  }
-
-  public final class NavArgsLazyKt {
-  }
-
-  public final class NavArgument {
-    method public Object? getDefaultValue();
-    method public androidx.navigation.NavType<java.lang.Object> getType();
-    method public boolean isDefaultValuePresent();
-    method public boolean isNullable();
-    property public final Object? defaultValue;
-    property public final boolean isDefaultValuePresent;
-    property public final boolean isNullable;
-    property public final androidx.navigation.NavType<java.lang.Object> type;
-  }
-
-  public static final class NavArgument.Builder {
-    ctor public NavArgument.Builder();
-    method public androidx.navigation.NavArgument build();
-    method public androidx.navigation.NavArgument.Builder setDefaultValue(Object? defaultValue);
-    method public androidx.navigation.NavArgument.Builder setIsNullable(boolean isNullable);
-    method public <T> androidx.navigation.NavArgument.Builder setType(androidx.navigation.NavType<T> type);
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class NavArgumentBuilder {
-    ctor public NavArgumentBuilder();
-    method public androidx.navigation.NavArgument build();
-    method public Object? getDefaultValue();
-    method public boolean getNullable();
-    method public androidx.navigation.NavType<?> getType();
-    method public void setDefaultValue(Object?);
-    method public void setNullable(boolean);
-    method public void setType(androidx.navigation.NavType<?>);
-    property public final Object? defaultValue;
-    property public final boolean nullable;
-    property public final androidx.navigation.NavType<?> type;
-  }
-
-  public final class NavBackStackEntry implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
-    method public android.os.Bundle? getArguments();
-    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
-    method public androidx.navigation.NavDestination getDestination();
-    method public String getId();
-    method public androidx.lifecycle.Lifecycle getLifecycle();
-    method public androidx.lifecycle.SavedStateHandle getSavedStateHandle();
-    method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
-    method public androidx.lifecycle.ViewModelStore getViewModelStore();
-    property public final android.os.Bundle? arguments;
-    property public final androidx.navigation.NavDestination destination;
-    property public final String id;
-    property public final androidx.lifecycle.SavedStateHandle savedStateHandle;
-    property public androidx.savedstate.SavedStateRegistry savedStateRegistry;
-  }
-
-  public final class NavDeepLink {
-    method public String? getAction();
-    method public String? getMimeType();
-    method public String? getUriPattern();
-    property public final String? action;
-    property public final String? mimeType;
-    property public final String? uriPattern;
-  }
-
-  public static final class NavDeepLink.Builder {
-    method public androidx.navigation.NavDeepLink build();
-    method public static androidx.navigation.NavDeepLink.Builder fromAction(String action);
-    method public static androidx.navigation.NavDeepLink.Builder fromMimeType(String mimeType);
-    method public static androidx.navigation.NavDeepLink.Builder fromUriPattern(String uriPattern);
-    method public androidx.navigation.NavDeepLink.Builder setAction(String action);
-    method public androidx.navigation.NavDeepLink.Builder setMimeType(String mimeType);
-    method public androidx.navigation.NavDeepLink.Builder setUriPattern(String uriPattern);
-  }
-
-  @kotlin.DslMarker public @interface NavDeepLinkDsl {
-  }
-
-  @androidx.navigation.NavDeepLinkDsl public final class NavDeepLinkDslBuilder {
-    ctor public NavDeepLinkDslBuilder();
-    method public String? getAction();
-    method public String? getMimeType();
-    method public String? getUriPattern();
-    method public void setAction(String?);
-    method public void setMimeType(String?);
-    method public void setUriPattern(String?);
-    property public final String? action;
-    property public final String? mimeType;
-    property public final String? uriPattern;
-  }
-
-  public final class NavDeepLinkDslBuilderKt {
-    method public static androidx.navigation.NavDeepLink navDeepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
-  }
-
-  public class NavDeepLinkRequest {
-    method public String? getAction();
-    method public String? getMimeType();
-    method public android.net.Uri? getUri();
-    property public String? action;
-    property public String? mimeType;
-    property public android.net.Uri? uri;
-  }
-
-  public static final class NavDeepLinkRequest.Builder {
-    method public androidx.navigation.NavDeepLinkRequest build();
-    method public static androidx.navigation.NavDeepLinkRequest.Builder fromAction(String action);
-    method public static androidx.navigation.NavDeepLinkRequest.Builder fromMimeType(String mimeType);
-    method public static androidx.navigation.NavDeepLinkRequest.Builder fromUri(android.net.Uri uri);
-    method public androidx.navigation.NavDeepLinkRequest.Builder setAction(String action);
-    method public androidx.navigation.NavDeepLinkRequest.Builder setMimeType(String mimeType);
-    method public androidx.navigation.NavDeepLinkRequest.Builder setUri(android.net.Uri uri);
-    field public static final androidx.navigation.NavDeepLinkRequest.Builder.Companion Companion;
-  }
-
-  public static final class NavDeepLinkRequest.Builder.Companion {
-    method public androidx.navigation.NavDeepLinkRequest.Builder fromAction(String action);
-    method public androidx.navigation.NavDeepLinkRequest.Builder fromMimeType(String mimeType);
-    method public androidx.navigation.NavDeepLinkRequest.Builder fromUri(android.net.Uri uri);
-  }
-
-  public class NavDestination {
-    ctor public NavDestination(String navigatorName);
-    ctor public NavDestination(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-    method public final void addArgument(String argumentName, androidx.navigation.NavArgument argument);
-    method public final void addDeepLink(String uriPattern);
-    method public final void addDeepLink(androidx.navigation.NavDeepLink navDeepLink);
-    method public final androidx.navigation.NavAction? getAction(@IdRes int id);
-    method public final java.util.Map<java.lang.String,androidx.navigation.NavArgument> getArguments();
-    method public static final kotlin.sequences.Sequence<androidx.navigation.NavDestination> getHierarchy(androidx.navigation.NavDestination);
-    method @IdRes public final int getId();
-    method public final CharSequence? getLabel();
-    method public final String getNavigatorName();
-    method public final androidx.navigation.NavGraph? getParent();
-    method public final String? getRoute();
-    method public boolean hasDeepLink(android.net.Uri deepLink);
-    method public boolean hasDeepLink(androidx.navigation.NavDeepLinkRequest deepLinkRequest);
-    method @CallSuper public void onInflate(android.content.Context context, android.util.AttributeSet attrs);
-    method protected static final <C> Class<? extends C> parseClassFromName(android.content.Context context, String name, Class<? extends C> expectedClassType);
-    method public final void putAction(@IdRes int actionId, @IdRes int destId);
-    method public final void putAction(@IdRes int actionId, androidx.navigation.NavAction action);
-    method public final void removeAction(@IdRes int actionId);
-    method public final void removeArgument(String argumentName);
-    method public final void setId(@IdRes int);
-    method public final void setLabel(CharSequence?);
-    method public final void setRoute(String?);
-    property public final java.util.Map<java.lang.String,androidx.navigation.NavArgument> arguments;
-    property @IdRes public final int id;
-    property public final CharSequence? label;
-    property public final String navigatorName;
-    property public final androidx.navigation.NavGraph? parent;
-    property public final String? route;
-    field public static final androidx.navigation.NavDestination.Companion Companion;
-  }
-
-  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface NavDestination.ClassType {
-    method public abstract kotlin.reflect.KClass<?> value();
-    property public abstract kotlin.reflect.KClass<?> value;
-  }
-
-  public static final class NavDestination.Companion {
-    method public kotlin.sequences.Sequence<androidx.navigation.NavDestination> getHierarchy(androidx.navigation.NavDestination);
-    method protected <C> Class<? extends C> parseClassFromName(android.content.Context context, String name, Class<? extends C> expectedClassType);
-  }
-
-  @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
-    ctor @Deprecated public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
-    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, String? route);
-    method @Deprecated public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
-    method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
-    method public D build();
-    method public final void deepLink(String uriPattern);
-    method public final void deepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> navDeepLink);
-    method public final int getId();
-    method public final CharSequence? getLabel();
-    method protected final androidx.navigation.Navigator<? extends D> getNavigator();
-    method public final String? getRoute();
-    method public final void setLabel(CharSequence?);
-    property public final int id;
-    property public final CharSequence? label;
-    property protected final androidx.navigation.Navigator<? extends D> navigator;
-    property public final String? route;
-  }
-
-  @kotlin.DslMarker public @interface NavDestinationDsl {
-  }
-
-  public interface NavDirections {
-    method @IdRes public int getActionId();
-    method public android.os.Bundle getArguments();
-    property @IdRes public abstract int actionId;
-    property public abstract android.os.Bundle arguments;
-  }
-
-  public class NavGraph extends androidx.navigation.NavDestination implements java.lang.Iterable<androidx.navigation.NavDestination> kotlin.jvm.internal.markers.KMappedMarker {
-    ctor public NavGraph(androidx.navigation.Navigator<? extends androidx.navigation.NavGraph> navGraphNavigator);
-    method public final void addAll(androidx.navigation.NavGraph other);
-    method public final void addDestination(androidx.navigation.NavDestination node);
-    method public final void addDestinations(java.util.Collection<? extends androidx.navigation.NavDestination> nodes);
-    method public final void addDestinations(androidx.navigation.NavDestination... nodes);
-    method public final void clear();
-    method public final androidx.navigation.NavDestination? findNode(@IdRes int resId);
-    method public final androidx.navigation.NavDestination? findNode(String? route);
-    method public static final androidx.navigation.NavDestination findStartDestination(androidx.navigation.NavGraph);
-    method @Deprecated @IdRes public final int getStartDestination();
-    method @IdRes public final int getStartDestinationId();
-    method public final String? getStartDestinationRoute();
-    method public final java.util.Iterator<androidx.navigation.NavDestination> iterator();
-    method public final void remove(androidx.navigation.NavDestination node);
-    method public final void setStartDestination(int startDestId);
-    method public final void setStartDestination(String startDestRoute);
-    property @IdRes public final int startDestinationId;
-    property public final String? startDestinationRoute;
-    field public static final androidx.navigation.NavGraph.Companion Companion;
-  }
-
-  public static final class NavGraph.Companion {
-    method public androidx.navigation.NavDestination findStartDestination(androidx.navigation.NavGraph);
-  }
-
-  @androidx.navigation.NavDestinationDsl public class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
-    ctor @Deprecated public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, String? route);
-    method public final void addDestination(androidx.navigation.NavDestination destination);
-    method public androidx.navigation.NavGraph build();
-    method public final <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
-    method public final androidx.navigation.NavigatorProvider getProvider();
-    method public final operator void unaryPlus(androidx.navigation.NavDestination);
-    property public final androidx.navigation.NavigatorProvider provider;
-  }
-
-  public final class NavGraphBuilderKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method @Deprecated public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavGraphKt {
-    method public static operator boolean contains(androidx.navigation.NavGraph, @IdRes int id);
-    method public static operator boolean contains(androidx.navigation.NavGraph, String route);
-    method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, @IdRes int id);
-    method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, String route);
-    method public static inline operator void minusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
-    method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
-    method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavGraph other);
-  }
-
-  @androidx.navigation.Navigator.Name("navigation") public class NavGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.NavGraph> {
-    ctor public NavGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider);
-    method public androidx.navigation.NavGraph createDestination();
-  }
-
-  public final class NavOptions {
-    method @AnimRes @AnimatorRes public int getEnterAnim();
-    method @AnimRes @AnimatorRes public int getExitAnim();
-    method @AnimRes @AnimatorRes public int getPopEnterAnim();
-    method @AnimRes @AnimatorRes public int getPopExitAnim();
-    method @Deprecated @IdRes public int getPopUpTo();
-    method @IdRes public int getPopUpToId();
-    method public String? getPopUpToRoute();
-    method public boolean isPopUpToInclusive();
-    method public boolean shouldLaunchSingleTop();
-    method public boolean shouldPopUpToSaveState();
-    method public boolean shouldRestoreState();
-    property @AnimRes @AnimatorRes public final int enterAnim;
-    property @AnimRes @AnimatorRes public final int exitAnim;
-    property @AnimRes @AnimatorRes public final int popEnterAnim;
-    property @AnimRes @AnimatorRes public final int popExitAnim;
-    property @IdRes public final int popUpToId;
-    property public final String? popUpToRoute;
-  }
-
-  public static final class NavOptions.Builder {
-    ctor public NavOptions.Builder();
-    method public androidx.navigation.NavOptions build();
-    method public androidx.navigation.NavOptions.Builder setEnterAnim(@AnimRes @AnimatorRes int enterAnim);
-    method public androidx.navigation.NavOptions.Builder setExitAnim(@AnimRes @AnimatorRes int exitAnim);
-    method public androidx.navigation.NavOptions.Builder setLaunchSingleTop(boolean singleTop);
-    method public androidx.navigation.NavOptions.Builder setPopEnterAnim(@AnimRes @AnimatorRes int popEnterAnim);
-    method public androidx.navigation.NavOptions.Builder setPopExitAnim(@AnimRes @AnimatorRes int popExitAnim);
-    method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int destinationId, boolean inclusive, optional boolean saveState);
-    method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int destinationId, boolean inclusive);
-    method public androidx.navigation.NavOptions.Builder setPopUpTo(String? route, boolean inclusive, optional boolean saveState);
-    method public androidx.navigation.NavOptions.Builder setPopUpTo(String? route, boolean inclusive);
-    method public androidx.navigation.NavOptions.Builder setRestoreState(boolean restoreState);
-  }
-
-  @androidx.navigation.NavOptionsDsl public final class NavOptionsBuilder {
-    ctor public NavOptionsBuilder();
-    method public void anim(kotlin.jvm.functions.Function1<? super androidx.navigation.AnimBuilder,kotlin.Unit> animBuilder);
-    method public boolean getLaunchSingleTop();
-    method @Deprecated public int getPopUpTo();
-    method public int getPopUpToId();
-    method public String? getPopUpToRoute();
-    method public boolean getRestoreState();
-    method public void popUpTo(@IdRes int id, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
-    method public void popUpTo(String route, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
-    method public void setLaunchSingleTop(boolean);
-    method @Deprecated public void setPopUpTo(int);
-    method public void setRestoreState(boolean);
-    property public final boolean launchSingleTop;
-    property @Deprecated public final int popUpTo;
-    property public final int popUpToId;
-    property public final String? popUpToRoute;
-    property public final boolean restoreState;
-  }
-
-  public final class NavOptionsBuilderKt {
-    method public static androidx.navigation.NavOptions navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
-  }
-
-  @kotlin.DslMarker public @interface NavOptionsDsl {
-  }
-
-  public abstract class NavType<T> {
-    ctor public NavType(boolean isNullableAllowed);
-    method public static androidx.navigation.NavType<?> fromArgType(String? type, String? packageName);
-    method public abstract operator T? get(android.os.Bundle bundle, String key);
-    method public String getName();
-    method public boolean isNullableAllowed();
-    method public abstract T! parseValue(String value);
-    method public abstract void put(android.os.Bundle bundle, String key, T? value);
-    property public boolean isNullableAllowed;
-    property public String name;
-    field public static final androidx.navigation.NavType<boolean[]> BoolArrayType;
-    field public static final androidx.navigation.NavType<java.lang.Boolean> BoolType;
-    field public static final androidx.navigation.NavType.Companion Companion;
-    field public static final androidx.navigation.NavType<float[]> FloatArrayType;
-    field public static final androidx.navigation.NavType<java.lang.Float> FloatType;
-    field public static final androidx.navigation.NavType<int[]> IntArrayType;
-    field public static final androidx.navigation.NavType<java.lang.Integer> IntType;
-    field public static final androidx.navigation.NavType<long[]> LongArrayType;
-    field public static final androidx.navigation.NavType<java.lang.Long> LongType;
-    field public static final androidx.navigation.NavType<java.lang.Integer> ReferenceType;
-    field public static final androidx.navigation.NavType<java.lang.String[]> StringArrayType;
-    field public static final androidx.navigation.NavType<java.lang.String> StringType;
-  }
-
-  public static final class NavType.Companion {
-    method public androidx.navigation.NavType<?> fromArgType(String? type, String? packageName);
-  }
-
-  public static final class NavType.EnumType<D extends java.lang.Enum<?>> extends androidx.navigation.NavType.SerializableType<D> {
-    ctor public NavType.EnumType(Class<D> type);
-    property public String name;
-  }
-
-  public static final class NavType.ParcelableArrayType<D extends android.os.Parcelable> extends androidx.navigation.NavType<D[]> {
-    ctor public NavType.ParcelableArrayType(Class<D> type);
-    method public D![]? get(android.os.Bundle bundle, String key);
-    method public D![] parseValue(String value);
-    method public void put(android.os.Bundle bundle, String key, D![]? value);
-    property public String name;
-  }
-
-  public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
-    ctor public NavType.ParcelableType(Class<D> type);
-    method public D? get(android.os.Bundle bundle, String key);
-    method public D! parseValue(String value);
-    method public void put(android.os.Bundle bundle, String key, D? value);
-    property public String name;
-  }
-
-  public static final class NavType.SerializableArrayType<D extends java.io.Serializable> extends androidx.navigation.NavType<D[]> {
-    ctor public NavType.SerializableArrayType(Class<D> type);
-    method public D![]? get(android.os.Bundle bundle, String key);
-    method public D![] parseValue(String value);
-    method public void put(android.os.Bundle bundle, String key, D![]? value);
-    property public String name;
-  }
-
-  public static class NavType.SerializableType<D extends java.io.Serializable> extends androidx.navigation.NavType<D> {
-    ctor public NavType.SerializableType(Class<D> type);
-    method public D? get(android.os.Bundle bundle, String key);
-    method public D parseValue(String value);
-    method public void put(android.os.Bundle bundle, String key, D value);
-    property public String name;
-  }
-
-  public abstract class Navigator<D extends androidx.navigation.NavDestination> {
-    ctor public Navigator();
-    method public abstract D createDestination();
-    method protected final androidx.navigation.NavigatorState getState();
-    method public final boolean isAttached();
-    method public void navigate(java.util.List<androidx.navigation.NavBackStackEntry> entries, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method public androidx.navigation.NavDestination? navigate(D destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method @CallSuper public void onAttach(androidx.navigation.NavigatorState state);
-    method public void onLaunchSingleTop(androidx.navigation.NavBackStackEntry backStackEntry);
-    method public void onRestoreState(android.os.Bundle savedState);
-    method public android.os.Bundle? onSaveState();
-    method public void popBackStack(androidx.navigation.NavBackStackEntry popUpTo, boolean savedState);
-    method public boolean popBackStack();
-    property public final boolean isAttached;
-    property protected final androidx.navigation.NavigatorState state;
-  }
-
-  public static interface Navigator.Extras {
-  }
-
-  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface Navigator.Name {
-    method public abstract String value();
-    property public abstract String value;
-  }
-
-  public class NavigatorProvider {
-    ctor public NavigatorProvider();
-    method public final androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? addNavigator(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-    method @CallSuper public androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? addNavigator(String name, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-    method public final <T extends androidx.navigation.Navigator<?>> T getNavigator(Class<T> navigatorClass);
-    method @CallSuper public <T extends androidx.navigation.Navigator<?>> T getNavigator(String name);
-  }
-
-  public final class NavigatorProviderKt {
-    method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, String name);
-    method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<T> clazz);
-    method public static inline operator void plusAssign(androidx.navigation.NavigatorProvider, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-    method public static inline operator androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? set(androidx.navigation.NavigatorProvider, String name, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-  }
-
-  public abstract class NavigatorState {
-    ctor public NavigatorState();
-    method public abstract androidx.navigation.NavBackStackEntry createBackStackEntry(androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
-    method public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getBackStack();
-    method public final kotlinx.coroutines.flow.StateFlow<java.util.Set<androidx.navigation.NavBackStackEntry>> getTransitionsInProgress();
-    method public void markTransitionComplete(androidx.navigation.NavBackStackEntry entry);
-    method @CallSuper public void onLaunchSingleTop(androidx.navigation.NavBackStackEntry backStackEntry);
-    method public void pop(androidx.navigation.NavBackStackEntry popUpTo, boolean saveState);
-    method public void popWithTransition(androidx.navigation.NavBackStackEntry popUpTo, boolean saveState);
-    method public void push(androidx.navigation.NavBackStackEntry backStackEntry);
-    method public void pushWithTransition(androidx.navigation.NavBackStackEntry backStackEntry);
-    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> backStack;
-    property public final kotlinx.coroutines.flow.StateFlow<java.util.Set<androidx.navigation.NavBackStackEntry>> transitionsInProgress;
-  }
-
-  @androidx.navigation.NavOptionsDsl public final class PopUpToBuilder {
-    ctor public PopUpToBuilder();
-    method public boolean getInclusive();
-    method public boolean getSaveState();
-    method public void setInclusive(boolean);
-    method public void setSaveState(boolean);
-    property public final boolean inclusive;
-    property public final boolean saveState;
-  }
-
-}
-
diff --git a/navigation/navigation-common/api/res-2.5.0-beta01.txt b/navigation/navigation-common/api/res-2.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/navigation/navigation-common/api/res-2.5.0-beta01.txt
+++ /dev/null
diff --git a/navigation/navigation-common/api/restricted_2.5.0-beta01.txt b/navigation/navigation-common/api/restricted_2.5.0-beta01.txt
deleted file mode 100644
index fe9681f..0000000
--- a/navigation/navigation-common/api/restricted_2.5.0-beta01.txt
+++ /dev/null
@@ -1,522 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation {
-
-  public final class ActionOnlyNavDirections implements androidx.navigation.NavDirections {
-    ctor public ActionOnlyNavDirections(int actionId);
-    method public int component1();
-    method public androidx.navigation.ActionOnlyNavDirections copy(int actionId);
-    method public int getActionId();
-    method public android.os.Bundle getArguments();
-    property public int actionId;
-    property public android.os.Bundle arguments;
-  }
-
-  @androidx.navigation.NavOptionsDsl public final class AnimBuilder {
-    ctor public AnimBuilder();
-    method public int getEnter();
-    method public int getExit();
-    method public int getPopEnter();
-    method public int getPopExit();
-    method public void setEnter(int);
-    method public void setExit(int);
-    method public void setPopEnter(int);
-    method public void setPopExit(int);
-    property public final int enter;
-    property public final int exit;
-    property public final int popEnter;
-    property public final int popExit;
-  }
-
-  public interface FloatingWindow {
-  }
-
-  public final class NamedNavArgument {
-    method public operator String component1();
-    method public operator androidx.navigation.NavArgument component2();
-    method public androidx.navigation.NavArgument getArgument();
-    method public String getName();
-    property public final androidx.navigation.NavArgument argument;
-    property public final String name;
-  }
-
-  public final class NamedNavArgumentKt {
-    method public static androidx.navigation.NamedNavArgument navArgument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavAction {
-    ctor public NavAction(@IdRes int destinationId, optional androidx.navigation.NavOptions? navOptions, optional android.os.Bundle? defaultArguments);
-    ctor public NavAction(@IdRes int destinationId, optional androidx.navigation.NavOptions? navOptions);
-    ctor public NavAction(@IdRes int destinationId);
-    method public android.os.Bundle? getDefaultArguments();
-    method public int getDestinationId();
-    method public androidx.navigation.NavOptions? getNavOptions();
-    method public void setDefaultArguments(android.os.Bundle?);
-    method public void setNavOptions(androidx.navigation.NavOptions?);
-    property public final android.os.Bundle? defaultArguments;
-    property public final int destinationId;
-    property public final androidx.navigation.NavOptions? navOptions;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class NavActionBuilder {
-    ctor public NavActionBuilder();
-    method public java.util.Map<java.lang.String,java.lang.Object> getDefaultArguments();
-    method public int getDestinationId();
-    method public void navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
-    method public void setDestinationId(int);
-    property public final java.util.Map<java.lang.String,java.lang.Object> defaultArguments;
-    property public final int destinationId;
-  }
-
-  public interface NavArgs {
-  }
-
-  public final class NavArgsLazy<Args extends androidx.navigation.NavArgs> implements kotlin.Lazy<Args> {
-    ctor public NavArgsLazy(kotlin.reflect.KClass<Args> navArgsClass, kotlin.jvm.functions.Function0<android.os.Bundle> argumentProducer);
-    method public Args getValue();
-    method public boolean isInitialized();
-    property public Args value;
-  }
-
-  public final class NavArgsLazyKt {
-  }
-
-  public final class NavArgument {
-    method public Object? getDefaultValue();
-    method public androidx.navigation.NavType<java.lang.Object> getType();
-    method public boolean isDefaultValuePresent();
-    method public boolean isNullable();
-    property public final Object? defaultValue;
-    property public final boolean isDefaultValuePresent;
-    property public final boolean isNullable;
-    property public final androidx.navigation.NavType<java.lang.Object> type;
-  }
-
-  public static final class NavArgument.Builder {
-    ctor public NavArgument.Builder();
-    method public androidx.navigation.NavArgument build();
-    method public androidx.navigation.NavArgument.Builder setDefaultValue(Object? defaultValue);
-    method public androidx.navigation.NavArgument.Builder setIsNullable(boolean isNullable);
-    method public <T> androidx.navigation.NavArgument.Builder setType(androidx.navigation.NavType<T> type);
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class NavArgumentBuilder {
-    ctor public NavArgumentBuilder();
-    method public androidx.navigation.NavArgument build();
-    method public Object? getDefaultValue();
-    method public boolean getNullable();
-    method public androidx.navigation.NavType<?> getType();
-    method public void setDefaultValue(Object?);
-    method public void setNullable(boolean);
-    method public void setType(androidx.navigation.NavType<?>);
-    property public final Object? defaultValue;
-    property public final boolean nullable;
-    property public final androidx.navigation.NavType<?> type;
-  }
-
-  public final class NavBackStackEntry implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
-    method public android.os.Bundle? getArguments();
-    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
-    method public androidx.navigation.NavDestination getDestination();
-    method public String getId();
-    method public androidx.lifecycle.Lifecycle getLifecycle();
-    method public androidx.lifecycle.SavedStateHandle getSavedStateHandle();
-    method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
-    method public androidx.lifecycle.ViewModelStore getViewModelStore();
-    property public final android.os.Bundle? arguments;
-    property public final androidx.navigation.NavDestination destination;
-    property public final String id;
-    property public final androidx.lifecycle.SavedStateHandle savedStateHandle;
-    property public androidx.savedstate.SavedStateRegistry savedStateRegistry;
-  }
-
-  public final class NavDeepLink {
-    method public String? getAction();
-    method public String? getMimeType();
-    method public String? getUriPattern();
-    property public final String? action;
-    property public final String? mimeType;
-    property public final String? uriPattern;
-  }
-
-  public static final class NavDeepLink.Builder {
-    method public androidx.navigation.NavDeepLink build();
-    method public static androidx.navigation.NavDeepLink.Builder fromAction(String action);
-    method public static androidx.navigation.NavDeepLink.Builder fromMimeType(String mimeType);
-    method public static androidx.navigation.NavDeepLink.Builder fromUriPattern(String uriPattern);
-    method public androidx.navigation.NavDeepLink.Builder setAction(String action);
-    method public androidx.navigation.NavDeepLink.Builder setMimeType(String mimeType);
-    method public androidx.navigation.NavDeepLink.Builder setUriPattern(String uriPattern);
-  }
-
-  @kotlin.DslMarker public @interface NavDeepLinkDsl {
-  }
-
-  @androidx.navigation.NavDeepLinkDsl public final class NavDeepLinkDslBuilder {
-    ctor public NavDeepLinkDslBuilder();
-    method public String? getAction();
-    method public String? getMimeType();
-    method public String? getUriPattern();
-    method public void setAction(String?);
-    method public void setMimeType(String?);
-    method public void setUriPattern(String?);
-    property public final String? action;
-    property public final String? mimeType;
-    property public final String? uriPattern;
-  }
-
-  public final class NavDeepLinkDslBuilderKt {
-    method public static androidx.navigation.NavDeepLink navDeepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
-  }
-
-  public class NavDeepLinkRequest {
-    method public String? getAction();
-    method public String? getMimeType();
-    method public android.net.Uri? getUri();
-    property public String? action;
-    property public String? mimeType;
-    property public android.net.Uri? uri;
-  }
-
-  public static final class NavDeepLinkRequest.Builder {
-    method public androidx.navigation.NavDeepLinkRequest build();
-    method public static androidx.navigation.NavDeepLinkRequest.Builder fromAction(String action);
-    method public static androidx.navigation.NavDeepLinkRequest.Builder fromMimeType(String mimeType);
-    method public static androidx.navigation.NavDeepLinkRequest.Builder fromUri(android.net.Uri uri);
-    method public androidx.navigation.NavDeepLinkRequest.Builder setAction(String action);
-    method public androidx.navigation.NavDeepLinkRequest.Builder setMimeType(String mimeType);
-    method public androidx.navigation.NavDeepLinkRequest.Builder setUri(android.net.Uri uri);
-    field public static final androidx.navigation.NavDeepLinkRequest.Builder.Companion Companion;
-  }
-
-  public static final class NavDeepLinkRequest.Builder.Companion {
-    method public androidx.navigation.NavDeepLinkRequest.Builder fromAction(String action);
-    method public androidx.navigation.NavDeepLinkRequest.Builder fromMimeType(String mimeType);
-    method public androidx.navigation.NavDeepLinkRequest.Builder fromUri(android.net.Uri uri);
-  }
-
-  public class NavDestination {
-    ctor public NavDestination(String navigatorName);
-    ctor public NavDestination(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-    method public final void addArgument(String argumentName, androidx.navigation.NavArgument argument);
-    method public final void addDeepLink(String uriPattern);
-    method public final void addDeepLink(androidx.navigation.NavDeepLink navDeepLink);
-    method public final androidx.navigation.NavAction? getAction(@IdRes int id);
-    method public final java.util.Map<java.lang.String,androidx.navigation.NavArgument> getArguments();
-    method public static final kotlin.sequences.Sequence<androidx.navigation.NavDestination> getHierarchy(androidx.navigation.NavDestination);
-    method @IdRes public final int getId();
-    method public final CharSequence? getLabel();
-    method public final String getNavigatorName();
-    method public final androidx.navigation.NavGraph? getParent();
-    method public final String? getRoute();
-    method public boolean hasDeepLink(android.net.Uri deepLink);
-    method public boolean hasDeepLink(androidx.navigation.NavDeepLinkRequest deepLinkRequest);
-    method @CallSuper public void onInflate(android.content.Context context, android.util.AttributeSet attrs);
-    method protected static final <C> Class<? extends C> parseClassFromName(android.content.Context context, String name, Class<? extends C> expectedClassType);
-    method public final void putAction(@IdRes int actionId, @IdRes int destId);
-    method public final void putAction(@IdRes int actionId, androidx.navigation.NavAction action);
-    method public final void removeAction(@IdRes int actionId);
-    method public final void removeArgument(String argumentName);
-    method public final void setId(@IdRes int);
-    method public final void setLabel(CharSequence?);
-    method public final void setRoute(String?);
-    property public final java.util.Map<java.lang.String,androidx.navigation.NavArgument> arguments;
-    property @IdRes public final int id;
-    property public final CharSequence? label;
-    property public final String navigatorName;
-    property public final androidx.navigation.NavGraph? parent;
-    property public final String? route;
-    field public static final androidx.navigation.NavDestination.Companion Companion;
-  }
-
-  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface NavDestination.ClassType {
-    method public abstract kotlin.reflect.KClass<?> value();
-    property public abstract kotlin.reflect.KClass<?> value;
-  }
-
-  public static final class NavDestination.Companion {
-    method public kotlin.sequences.Sequence<androidx.navigation.NavDestination> getHierarchy(androidx.navigation.NavDestination);
-    method protected <C> Class<? extends C> parseClassFromName(android.content.Context context, String name, Class<? extends C> expectedClassType);
-  }
-
-  @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
-    ctor @Deprecated public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
-    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, String? route);
-    method @Deprecated public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
-    method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
-    method public D build();
-    method public final void deepLink(String uriPattern);
-    method public final void deepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> navDeepLink);
-    method public final int getId();
-    method public final CharSequence? getLabel();
-    method protected final androidx.navigation.Navigator<? extends D> getNavigator();
-    method public final String? getRoute();
-    method public final void setLabel(CharSequence?);
-    property public final int id;
-    property public final CharSequence? label;
-    property protected final androidx.navigation.Navigator<? extends D> navigator;
-    property public final String? route;
-  }
-
-  @kotlin.DslMarker public @interface NavDestinationDsl {
-  }
-
-  public interface NavDirections {
-    method @IdRes public int getActionId();
-    method public android.os.Bundle getArguments();
-    property @IdRes public abstract int actionId;
-    property public abstract android.os.Bundle arguments;
-  }
-
-  public class NavGraph extends androidx.navigation.NavDestination implements java.lang.Iterable<androidx.navigation.NavDestination> kotlin.jvm.internal.markers.KMappedMarker {
-    ctor public NavGraph(androidx.navigation.Navigator<? extends androidx.navigation.NavGraph> navGraphNavigator);
-    method public final void addAll(androidx.navigation.NavGraph other);
-    method public final void addDestination(androidx.navigation.NavDestination node);
-    method public final void addDestinations(java.util.Collection<? extends androidx.navigation.NavDestination> nodes);
-    method public final void addDestinations(androidx.navigation.NavDestination... nodes);
-    method public final void clear();
-    method public final androidx.navigation.NavDestination? findNode(@IdRes int resId);
-    method public final androidx.navigation.NavDestination? findNode(String? route);
-    method public static final androidx.navigation.NavDestination findStartDestination(androidx.navigation.NavGraph);
-    method @Deprecated @IdRes public final int getStartDestination();
-    method @IdRes public final int getStartDestinationId();
-    method public final String? getStartDestinationRoute();
-    method public final java.util.Iterator<androidx.navigation.NavDestination> iterator();
-    method public final void remove(androidx.navigation.NavDestination node);
-    method public final void setStartDestination(int startDestId);
-    method public final void setStartDestination(String startDestRoute);
-    property @IdRes public final int startDestinationId;
-    property public final String? startDestinationRoute;
-    field public static final androidx.navigation.NavGraph.Companion Companion;
-  }
-
-  public static final class NavGraph.Companion {
-    method public androidx.navigation.NavDestination findStartDestination(androidx.navigation.NavGraph);
-  }
-
-  @androidx.navigation.NavDestinationDsl public class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
-    ctor @Deprecated public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, String? route);
-    method public final void addDestination(androidx.navigation.NavDestination destination);
-    method public androidx.navigation.NavGraph build();
-    method public final <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
-    method public final androidx.navigation.NavigatorProvider getProvider();
-    method public final operator void unaryPlus(androidx.navigation.NavDestination);
-    property public final androidx.navigation.NavigatorProvider provider;
-  }
-
-  public final class NavGraphBuilderKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method @Deprecated public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavGraphKt {
-    method public static operator boolean contains(androidx.navigation.NavGraph, @IdRes int id);
-    method public static operator boolean contains(androidx.navigation.NavGraph, String route);
-    method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, @IdRes int id);
-    method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, String route);
-    method public static inline operator void minusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
-    method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
-    method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavGraph other);
-  }
-
-  @androidx.navigation.Navigator.Name("navigation") public class NavGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.NavGraph> {
-    ctor public NavGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider);
-    method public androidx.navigation.NavGraph createDestination();
-  }
-
-  public final class NavOptions {
-    method @AnimRes @AnimatorRes public int getEnterAnim();
-    method @AnimRes @AnimatorRes public int getExitAnim();
-    method @AnimRes @AnimatorRes public int getPopEnterAnim();
-    method @AnimRes @AnimatorRes public int getPopExitAnim();
-    method @Deprecated @IdRes public int getPopUpTo();
-    method @IdRes public int getPopUpToId();
-    method public String? getPopUpToRoute();
-    method public boolean isPopUpToInclusive();
-    method public boolean shouldLaunchSingleTop();
-    method public boolean shouldPopUpToSaveState();
-    method public boolean shouldRestoreState();
-    property @AnimRes @AnimatorRes public final int enterAnim;
-    property @AnimRes @AnimatorRes public final int exitAnim;
-    property @AnimRes @AnimatorRes public final int popEnterAnim;
-    property @AnimRes @AnimatorRes public final int popExitAnim;
-    property @IdRes public final int popUpToId;
-    property public final String? popUpToRoute;
-  }
-
-  public static final class NavOptions.Builder {
-    ctor public NavOptions.Builder();
-    method public androidx.navigation.NavOptions build();
-    method public androidx.navigation.NavOptions.Builder setEnterAnim(@AnimRes @AnimatorRes int enterAnim);
-    method public androidx.navigation.NavOptions.Builder setExitAnim(@AnimRes @AnimatorRes int exitAnim);
-    method public androidx.navigation.NavOptions.Builder setLaunchSingleTop(boolean singleTop);
-    method public androidx.navigation.NavOptions.Builder setPopEnterAnim(@AnimRes @AnimatorRes int popEnterAnim);
-    method public androidx.navigation.NavOptions.Builder setPopExitAnim(@AnimRes @AnimatorRes int popExitAnim);
-    method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int destinationId, boolean inclusive, optional boolean saveState);
-    method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int destinationId, boolean inclusive);
-    method public androidx.navigation.NavOptions.Builder setPopUpTo(String? route, boolean inclusive, optional boolean saveState);
-    method public androidx.navigation.NavOptions.Builder setPopUpTo(String? route, boolean inclusive);
-    method public androidx.navigation.NavOptions.Builder setRestoreState(boolean restoreState);
-  }
-
-  @androidx.navigation.NavOptionsDsl public final class NavOptionsBuilder {
-    ctor public NavOptionsBuilder();
-    method public void anim(kotlin.jvm.functions.Function1<? super androidx.navigation.AnimBuilder,kotlin.Unit> animBuilder);
-    method public boolean getLaunchSingleTop();
-    method @Deprecated public int getPopUpTo();
-    method public int getPopUpToId();
-    method public String? getPopUpToRoute();
-    method public boolean getRestoreState();
-    method public void popUpTo(@IdRes int id, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
-    method public void popUpTo(String route, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
-    method public void setLaunchSingleTop(boolean);
-    method @Deprecated public void setPopUpTo(int);
-    method public void setRestoreState(boolean);
-    property public final boolean launchSingleTop;
-    property @Deprecated public final int popUpTo;
-    property public final int popUpToId;
-    property public final String? popUpToRoute;
-    property public final boolean restoreState;
-  }
-
-  public final class NavOptionsBuilderKt {
-    method public static androidx.navigation.NavOptions navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
-  }
-
-  @kotlin.DslMarker public @interface NavOptionsDsl {
-  }
-
-  public abstract class NavType<T> {
-    ctor public NavType(boolean isNullableAllowed);
-    method public static androidx.navigation.NavType<?> fromArgType(String? type, String? packageName);
-    method public abstract operator T? get(android.os.Bundle bundle, String key);
-    method public String getName();
-    method public boolean isNullableAllowed();
-    method public abstract T! parseValue(String value);
-    method public abstract void put(android.os.Bundle bundle, String key, T? value);
-    property public boolean isNullableAllowed;
-    property public String name;
-    field public static final androidx.navigation.NavType<boolean[]> BoolArrayType;
-    field public static final androidx.navigation.NavType<java.lang.Boolean> BoolType;
-    field public static final androidx.navigation.NavType.Companion Companion;
-    field public static final androidx.navigation.NavType<float[]> FloatArrayType;
-    field public static final androidx.navigation.NavType<java.lang.Float> FloatType;
-    field public static final androidx.navigation.NavType<int[]> IntArrayType;
-    field public static final androidx.navigation.NavType<java.lang.Integer> IntType;
-    field public static final androidx.navigation.NavType<long[]> LongArrayType;
-    field public static final androidx.navigation.NavType<java.lang.Long> LongType;
-    field public static final androidx.navigation.NavType<java.lang.Integer> ReferenceType;
-    field public static final androidx.navigation.NavType<java.lang.String[]> StringArrayType;
-    field public static final androidx.navigation.NavType<java.lang.String> StringType;
-  }
-
-  public static final class NavType.Companion {
-    method public androidx.navigation.NavType<?> fromArgType(String? type, String? packageName);
-  }
-
-  public static final class NavType.EnumType<D extends java.lang.Enum<?>> extends androidx.navigation.NavType.SerializableType<D> {
-    ctor public NavType.EnumType(Class<D> type);
-    property public String name;
-  }
-
-  public static final class NavType.ParcelableArrayType<D extends android.os.Parcelable> extends androidx.navigation.NavType<D[]> {
-    ctor public NavType.ParcelableArrayType(Class<D> type);
-    method public D![]? get(android.os.Bundle bundle, String key);
-    method public D![] parseValue(String value);
-    method public void put(android.os.Bundle bundle, String key, D![]? value);
-    property public String name;
-  }
-
-  public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
-    ctor public NavType.ParcelableType(Class<D> type);
-    method public D? get(android.os.Bundle bundle, String key);
-    method public D! parseValue(String value);
-    method public void put(android.os.Bundle bundle, String key, D? value);
-    property public String name;
-  }
-
-  public static final class NavType.SerializableArrayType<D extends java.io.Serializable> extends androidx.navigation.NavType<D[]> {
-    ctor public NavType.SerializableArrayType(Class<D> type);
-    method public D![]? get(android.os.Bundle bundle, String key);
-    method public D![] parseValue(String value);
-    method public void put(android.os.Bundle bundle, String key, D![]? value);
-    property public String name;
-  }
-
-  public static class NavType.SerializableType<D extends java.io.Serializable> extends androidx.navigation.NavType<D> {
-    ctor public NavType.SerializableType(Class<D> type);
-    method public D? get(android.os.Bundle bundle, String key);
-    method public D parseValue(String value);
-    method public void put(android.os.Bundle bundle, String key, D value);
-    property public String name;
-  }
-
-  public abstract class Navigator<D extends androidx.navigation.NavDestination> {
-    ctor public Navigator();
-    method public abstract D createDestination();
-    method protected final androidx.navigation.NavigatorState getState();
-    method public final boolean isAttached();
-    method public void navigate(java.util.List<androidx.navigation.NavBackStackEntry> entries, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method public androidx.navigation.NavDestination? navigate(D destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method @CallSuper public void onAttach(androidx.navigation.NavigatorState state);
-    method public void onLaunchSingleTop(androidx.navigation.NavBackStackEntry backStackEntry);
-    method public void onRestoreState(android.os.Bundle savedState);
-    method public android.os.Bundle? onSaveState();
-    method public void popBackStack(androidx.navigation.NavBackStackEntry popUpTo, boolean savedState);
-    method public boolean popBackStack();
-    property public final boolean isAttached;
-    property protected final androidx.navigation.NavigatorState state;
-  }
-
-  public static interface Navigator.Extras {
-  }
-
-  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface Navigator.Name {
-    method public abstract String value();
-    property public abstract String value;
-  }
-
-  public class NavigatorProvider {
-    ctor public NavigatorProvider();
-    method public final androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? addNavigator(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-    method @CallSuper public androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? addNavigator(String name, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-    method public final <T extends androidx.navigation.Navigator<?>> T getNavigator(Class<T> navigatorClass);
-    method @CallSuper public <T extends androidx.navigation.Navigator<?>> T getNavigator(String name);
-  }
-
-  public final class NavigatorProviderKt {
-    method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, String name);
-    method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<T> clazz);
-    method public static inline operator void plusAssign(androidx.navigation.NavigatorProvider, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-    method public static inline operator androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? set(androidx.navigation.NavigatorProvider, String name, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
-  }
-
-  public abstract class NavigatorState {
-    ctor public NavigatorState();
-    method public abstract androidx.navigation.NavBackStackEntry createBackStackEntry(androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
-    method public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getBackStack();
-    method public final kotlinx.coroutines.flow.StateFlow<java.util.Set<androidx.navigation.NavBackStackEntry>> getTransitionsInProgress();
-    method public void markTransitionComplete(androidx.navigation.NavBackStackEntry entry);
-    method @CallSuper public void onLaunchSingleTop(androidx.navigation.NavBackStackEntry backStackEntry);
-    method public void pop(androidx.navigation.NavBackStackEntry popUpTo, boolean saveState);
-    method public void popWithTransition(androidx.navigation.NavBackStackEntry popUpTo, boolean saveState);
-    method public void push(androidx.navigation.NavBackStackEntry backStackEntry);
-    method public void pushWithTransition(androidx.navigation.NavBackStackEntry backStackEntry);
-    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> backStack;
-    property public final kotlinx.coroutines.flow.StateFlow<java.util.Set<androidx.navigation.NavBackStackEntry>> transitionsInProgress;
-  }
-
-  @androidx.navigation.NavOptionsDsl public final class PopUpToBuilder {
-    ctor public PopUpToBuilder();
-    method public boolean getInclusive();
-    method public boolean getSaveState();
-    method public void setInclusive(boolean);
-    method public void setSaveState(boolean);
-    property public final boolean inclusive;
-    property public final boolean saveState;
-  }
-
-}
-
diff --git a/navigation/navigation-compose/api/2.5.0-beta01.txt b/navigation/navigation-compose/api/2.5.0-beta01.txt
deleted file mode 100644
index d46757e..0000000
--- a/navigation/navigation-compose/api/2.5.0-beta01.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.compose {
-
-  @androidx.navigation.Navigator.Name("composable") public final class ComposeNavigator extends androidx.navigation.Navigator<androidx.navigation.compose.ComposeNavigator.Destination> {
-    ctor public ComposeNavigator();
-    method public androidx.navigation.compose.ComposeNavigator.Destination createDestination();
-  }
-
-  @androidx.navigation.NavDestination.ClassType(Composable::class) public static final class ComposeNavigator.Destination extends androidx.navigation.NavDestination {
-    ctor public ComposeNavigator.Destination(androidx.navigation.compose.ComposeNavigator navigator, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-  }
-
-  public final class DialogHostKt {
-    method @androidx.compose.runtime.Composable public static void DialogHost(androidx.navigation.compose.DialogNavigator dialogNavigator);
-  }
-
-  @androidx.navigation.Navigator.Name("dialog") public final class DialogNavigator extends androidx.navigation.Navigator<androidx.navigation.compose.DialogNavigator.Destination> {
-    ctor public DialogNavigator();
-    method public androidx.navigation.compose.DialogNavigator.Destination createDestination();
-  }
-
-  @androidx.navigation.NavDestination.ClassType(Composable::class) public static final class DialogNavigator.Destination extends androidx.navigation.NavDestination implements androidx.navigation.FloatingWindow {
-    ctor public DialogNavigator.Destination(androidx.navigation.compose.DialogNavigator navigator, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-  }
-
-  public final class NavBackStackEntryProviderKt {
-    method @androidx.compose.runtime.Composable public static void LocalOwnersProvider(androidx.navigation.NavBackStackEntry, androidx.compose.runtime.saveable.SaveableStateHolder saveableStateHolder, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-  }
-
-  public final class NavGraphBuilderKt {
-    method public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static void dialog(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavHostControllerKt {
-    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.navigation.NavBackStackEntry> currentBackStackEntryAsState(androidx.navigation.NavController);
-    method @androidx.compose.runtime.Composable public static androidx.navigation.NavHostController rememberNavController(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>... navigators);
-  }
-
-  public final class NavHostKt {
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier);
-  }
-
-}
-
diff --git a/navigation/navigation-compose/api/public_plus_experimental_2.5.0-beta01.txt b/navigation/navigation-compose/api/public_plus_experimental_2.5.0-beta01.txt
deleted file mode 100644
index d46757e..0000000
--- a/navigation/navigation-compose/api/public_plus_experimental_2.5.0-beta01.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.compose {
-
-  @androidx.navigation.Navigator.Name("composable") public final class ComposeNavigator extends androidx.navigation.Navigator<androidx.navigation.compose.ComposeNavigator.Destination> {
-    ctor public ComposeNavigator();
-    method public androidx.navigation.compose.ComposeNavigator.Destination createDestination();
-  }
-
-  @androidx.navigation.NavDestination.ClassType(Composable::class) public static final class ComposeNavigator.Destination extends androidx.navigation.NavDestination {
-    ctor public ComposeNavigator.Destination(androidx.navigation.compose.ComposeNavigator navigator, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-  }
-
-  public final class DialogHostKt {
-    method @androidx.compose.runtime.Composable public static void DialogHost(androidx.navigation.compose.DialogNavigator dialogNavigator);
-  }
-
-  @androidx.navigation.Navigator.Name("dialog") public final class DialogNavigator extends androidx.navigation.Navigator<androidx.navigation.compose.DialogNavigator.Destination> {
-    ctor public DialogNavigator();
-    method public androidx.navigation.compose.DialogNavigator.Destination createDestination();
-  }
-
-  @androidx.navigation.NavDestination.ClassType(Composable::class) public static final class DialogNavigator.Destination extends androidx.navigation.NavDestination implements androidx.navigation.FloatingWindow {
-    ctor public DialogNavigator.Destination(androidx.navigation.compose.DialogNavigator navigator, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-  }
-
-  public final class NavBackStackEntryProviderKt {
-    method @androidx.compose.runtime.Composable public static void LocalOwnersProvider(androidx.navigation.NavBackStackEntry, androidx.compose.runtime.saveable.SaveableStateHolder saveableStateHolder, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-  }
-
-  public final class NavGraphBuilderKt {
-    method public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static void dialog(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavHostControllerKt {
-    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.navigation.NavBackStackEntry> currentBackStackEntryAsState(androidx.navigation.NavController);
-    method @androidx.compose.runtime.Composable public static androidx.navigation.NavHostController rememberNavController(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>... navigators);
-  }
-
-  public final class NavHostKt {
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier);
-  }
-
-}
-
diff --git a/navigation/navigation-compose/api/res-2.5.0-beta01.txt b/navigation/navigation-compose/api/res-2.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/navigation/navigation-compose/api/res-2.5.0-beta01.txt
+++ /dev/null
diff --git a/navigation/navigation-compose/api/restricted_2.5.0-beta01.txt b/navigation/navigation-compose/api/restricted_2.5.0-beta01.txt
deleted file mode 100644
index d46757e..0000000
--- a/navigation/navigation-compose/api/restricted_2.5.0-beta01.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.compose {
-
-  @androidx.navigation.Navigator.Name("composable") public final class ComposeNavigator extends androidx.navigation.Navigator<androidx.navigation.compose.ComposeNavigator.Destination> {
-    ctor public ComposeNavigator();
-    method public androidx.navigation.compose.ComposeNavigator.Destination createDestination();
-  }
-
-  @androidx.navigation.NavDestination.ClassType(Composable::class) public static final class ComposeNavigator.Destination extends androidx.navigation.NavDestination {
-    ctor public ComposeNavigator.Destination(androidx.navigation.compose.ComposeNavigator navigator, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-  }
-
-  public final class DialogHostKt {
-    method @androidx.compose.runtime.Composable public static void DialogHost(androidx.navigation.compose.DialogNavigator dialogNavigator);
-  }
-
-  @androidx.navigation.Navigator.Name("dialog") public final class DialogNavigator extends androidx.navigation.Navigator<androidx.navigation.compose.DialogNavigator.Destination> {
-    ctor public DialogNavigator();
-    method public androidx.navigation.compose.DialogNavigator.Destination createDestination();
-  }
-
-  @androidx.navigation.NavDestination.ClassType(Composable::class) public static final class DialogNavigator.Destination extends androidx.navigation.NavDestination implements androidx.navigation.FloatingWindow {
-    ctor public DialogNavigator.Destination(androidx.navigation.compose.DialogNavigator navigator, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-  }
-
-  public final class NavBackStackEntryProviderKt {
-    method @androidx.compose.runtime.Composable public static void LocalOwnersProvider(androidx.navigation.NavBackStackEntry, androidx.compose.runtime.saveable.SaveableStateHolder saveableStateHolder, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-  }
-
-  public final class NavGraphBuilderKt {
-    method public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static void dialog(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
-    method public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavHostControllerKt {
-    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.navigation.NavBackStackEntry> currentBackStackEntryAsState(androidx.navigation.NavController);
-    method @androidx.compose.runtime.Composable public static androidx.navigation.NavHostController rememberNavController(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>... navigators);
-  }
-
-  public final class NavHostKt {
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier);
-  }
-
-}
-
diff --git a/navigation/navigation-dynamic-features-fragment/api/2.5.0-beta01.txt b/navigation/navigation-dynamic-features-fragment/api/2.5.0-beta01.txt
deleted file mode 100644
index fe32d9b..0000000
--- a/navigation/navigation-dynamic-features-fragment/api/2.5.0-beta01.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.dynamicfeatures.fragment {
-
-  @androidx.navigation.Navigator.Name("fragment") public final class DynamicFragmentNavigator extends androidx.navigation.fragment.FragmentNavigator {
-    ctor public DynamicFragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager manager, int containerId, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
-    method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination createDestination();
-  }
-
-  public static final class DynamicFragmentNavigator.Destination extends androidx.navigation.fragment.FragmentNavigator.Destination {
-    ctor public DynamicFragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    ctor public DynamicFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> fragmentNavigator);
-    method public String? getModuleName();
-    method public void setModuleName(String?);
-    property public final String? moduleName;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DynamicFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor @Deprecated public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
-    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, String route, String fragmentClassName);
-    method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination build();
-    method public String? getModuleName();
-    method public void setModuleName(String?);
-    property public final String? moduleName;
-  }
-
-  public final class DynamicFragmentNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-  }
-
-  public class DynamicNavHostFragment extends androidx.navigation.fragment.NavHostFragment {
-    ctor public DynamicNavHostFragment();
-    method public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
-    method public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId);
-    method protected com.google.android.play.core.splitinstall.SplitInstallManager createSplitInstallManager();
-    field public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment.Companion Companion;
-  }
-
-  public static final class DynamicNavHostFragment.Companion {
-    method public androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
-    method public androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId);
-  }
-
-}
-
-package androidx.navigation.dynamicfeatures.fragment.ui {
-
-  public abstract class AbstractProgressFragment extends androidx.fragment.app.Fragment {
-    ctor public AbstractProgressFragment();
-    ctor public AbstractProgressFragment(int contentLayoutId);
-    method protected abstract void onCancelled();
-    method protected abstract void onFailed(@com.google.android.play.core.splitinstall.model.SplitInstallErrorCode int errorCode);
-    method protected void onInstalled();
-    method protected abstract void onProgress(@com.google.android.play.core.splitinstall.model.SplitInstallSessionStatus int status, long bytesDownloaded, long bytesTotal);
-  }
-
-  public final class DefaultProgressFragment extends androidx.navigation.dynamicfeatures.fragment.ui.AbstractProgressFragment {
-    ctor public DefaultProgressFragment();
-    method protected void onCancelled();
-    method protected void onFailed(@com.google.android.play.core.splitinstall.model.SplitInstallErrorCode int errorCode);
-    method protected void onProgress(int status, long bytesDownloaded, long bytesTotal);
-  }
-
-}
-
diff --git a/navigation/navigation-dynamic-features-fragment/api/public_plus_experimental_2.5.0-beta01.txt b/navigation/navigation-dynamic-features-fragment/api/public_plus_experimental_2.5.0-beta01.txt
deleted file mode 100644
index fe32d9b..0000000
--- a/navigation/navigation-dynamic-features-fragment/api/public_plus_experimental_2.5.0-beta01.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.dynamicfeatures.fragment {
-
-  @androidx.navigation.Navigator.Name("fragment") public final class DynamicFragmentNavigator extends androidx.navigation.fragment.FragmentNavigator {
-    ctor public DynamicFragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager manager, int containerId, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
-    method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination createDestination();
-  }
-
-  public static final class DynamicFragmentNavigator.Destination extends androidx.navigation.fragment.FragmentNavigator.Destination {
-    ctor public DynamicFragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    ctor public DynamicFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> fragmentNavigator);
-    method public String? getModuleName();
-    method public void setModuleName(String?);
-    property public final String? moduleName;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DynamicFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor @Deprecated public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
-    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, String route, String fragmentClassName);
-    method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination build();
-    method public String? getModuleName();
-    method public void setModuleName(String?);
-    property public final String? moduleName;
-  }
-
-  public final class DynamicFragmentNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-  }
-
-  public class DynamicNavHostFragment extends androidx.navigation.fragment.NavHostFragment {
-    ctor public DynamicNavHostFragment();
-    method public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
-    method public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId);
-    method protected com.google.android.play.core.splitinstall.SplitInstallManager createSplitInstallManager();
-    field public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment.Companion Companion;
-  }
-
-  public static final class DynamicNavHostFragment.Companion {
-    method public androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
-    method public androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId);
-  }
-
-}
-
-package androidx.navigation.dynamicfeatures.fragment.ui {
-
-  public abstract class AbstractProgressFragment extends androidx.fragment.app.Fragment {
-    ctor public AbstractProgressFragment();
-    ctor public AbstractProgressFragment(int contentLayoutId);
-    method protected abstract void onCancelled();
-    method protected abstract void onFailed(@com.google.android.play.core.splitinstall.model.SplitInstallErrorCode int errorCode);
-    method protected void onInstalled();
-    method protected abstract void onProgress(@com.google.android.play.core.splitinstall.model.SplitInstallSessionStatus int status, long bytesDownloaded, long bytesTotal);
-  }
-
-  public final class DefaultProgressFragment extends androidx.navigation.dynamicfeatures.fragment.ui.AbstractProgressFragment {
-    ctor public DefaultProgressFragment();
-    method protected void onCancelled();
-    method protected void onFailed(@com.google.android.play.core.splitinstall.model.SplitInstallErrorCode int errorCode);
-    method protected void onProgress(int status, long bytesDownloaded, long bytesTotal);
-  }
-
-}
-
diff --git a/navigation/navigation-dynamic-features-fragment/api/res-2.5.0-beta01.txt b/navigation/navigation-dynamic-features-fragment/api/res-2.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/navigation/navigation-dynamic-features-fragment/api/res-2.5.0-beta01.txt
+++ /dev/null
diff --git a/navigation/navigation-dynamic-features-fragment/api/restricted_2.5.0-beta01.txt b/navigation/navigation-dynamic-features-fragment/api/restricted_2.5.0-beta01.txt
deleted file mode 100644
index fe32d9b..0000000
--- a/navigation/navigation-dynamic-features-fragment/api/restricted_2.5.0-beta01.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.dynamicfeatures.fragment {
-
-  @androidx.navigation.Navigator.Name("fragment") public final class DynamicFragmentNavigator extends androidx.navigation.fragment.FragmentNavigator {
-    ctor public DynamicFragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager manager, int containerId, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
-    method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination createDestination();
-  }
-
-  public static final class DynamicFragmentNavigator.Destination extends androidx.navigation.fragment.FragmentNavigator.Destination {
-    ctor public DynamicFragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    ctor public DynamicFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> fragmentNavigator);
-    method public String? getModuleName();
-    method public void setModuleName(String?);
-    property public final String? moduleName;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DynamicFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor @Deprecated public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
-    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, String route, String fragmentClassName);
-    method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination build();
-    method public String? getModuleName();
-    method public void setModuleName(String?);
-    property public final String? moduleName;
-  }
-
-  public final class DynamicFragmentNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-  }
-
-  public class DynamicNavHostFragment extends androidx.navigation.fragment.NavHostFragment {
-    ctor public DynamicNavHostFragment();
-    method public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
-    method public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId);
-    method protected com.google.android.play.core.splitinstall.SplitInstallManager createSplitInstallManager();
-    field public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment.Companion Companion;
-  }
-
-  public static final class DynamicNavHostFragment.Companion {
-    method public androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
-    method public androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId);
-  }
-
-}
-
-package androidx.navigation.dynamicfeatures.fragment.ui {
-
-  public abstract class AbstractProgressFragment extends androidx.fragment.app.Fragment {
-    ctor public AbstractProgressFragment();
-    ctor public AbstractProgressFragment(int contentLayoutId);
-    method protected abstract void onCancelled();
-    method protected abstract void onFailed(@com.google.android.play.core.splitinstall.model.SplitInstallErrorCode int errorCode);
-    method protected void onInstalled();
-    method protected abstract void onProgress(@com.google.android.play.core.splitinstall.model.SplitInstallSessionStatus int status, long bytesDownloaded, long bytesTotal);
-  }
-
-  public final class DefaultProgressFragment extends androidx.navigation.dynamicfeatures.fragment.ui.AbstractProgressFragment {
-    ctor public DefaultProgressFragment();
-    method protected void onCancelled();
-    method protected void onFailed(@com.google.android.play.core.splitinstall.model.SplitInstallErrorCode int errorCode);
-    method protected void onProgress(int status, long bytesDownloaded, long bytesTotal);
-  }
-
-}
-
diff --git a/navigation/navigation-dynamic-features-runtime/api/2.5.0-beta01.txt b/navigation/navigation-dynamic-features-runtime/api/2.5.0-beta01.txt
deleted file mode 100644
index e4c37db..0000000
--- a/navigation/navigation-dynamic-features-runtime/api/2.5.0-beta01.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.dynamicfeatures {
-
-  @androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
-    ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
-    method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
-  }
-
-  public static final class DynamicActivityNavigator.Destination extends androidx.navigation.ActivityNavigator.Destination {
-    ctor public DynamicActivityNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    ctor public DynamicActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination> activityNavigator);
-    method public String? getModuleName();
-    method public void setModuleName(String?);
-    property public final String? moduleName;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DynamicActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
-    ctor @Deprecated public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
-    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, String route);
-    method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination build();
-    method public String? getAction();
-    method public String? getActivityClassName();
-    method public android.net.Uri? getData();
-    method public String? getDataPattern();
-    method public String? getModuleName();
-    method public String? getTargetPackage();
-    method public void setAction(String?);
-    method public void setActivityClassName(String?);
-    method public void setData(android.net.Uri?);
-    method public void setDataPattern(String?);
-    method public void setModuleName(String?);
-    method public void setTargetPackage(String?);
-    property public final String? action;
-    property public final String? activityClassName;
-    property public final android.net.Uri? data;
-    property public final String? dataPattern;
-    property public final String? moduleName;
-    property public final String? targetPackage;
-  }
-
-  public final class DynamicActivityNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-  }
-
-  public final class DynamicExtras implements androidx.navigation.Navigator.Extras {
-    ctor public DynamicExtras(optional androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor, optional androidx.navigation.Navigator.Extras? destinationExtras);
-    ctor public DynamicExtras(optional androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor);
-    ctor public DynamicExtras();
-    method public androidx.navigation.Navigator.Extras? getDestinationExtras();
-    method public androidx.navigation.dynamicfeatures.DynamicInstallMonitor? getInstallMonitor();
-    property public final androidx.navigation.Navigator.Extras? destinationExtras;
-    property public final androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor;
-  }
-
-  @androidx.navigation.Navigator.Name("navigation") public final class DynamicGraphNavigator extends androidx.navigation.NavGraphNavigator {
-    ctor public DynamicGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
-    method public androidx.navigation.dynamicfeatures.DynamicGraphNavigator.DynamicNavGraph createDestination();
-    method public void installDefaultProgressDestination(kotlin.jvm.functions.Function0<? extends androidx.navigation.NavDestination> progressDestinationSupplier);
-  }
-
-  public static final class DynamicGraphNavigator.DynamicNavGraph extends androidx.navigation.NavGraph {
-    ctor public DynamicGraphNavigator.DynamicNavGraph(androidx.navigation.dynamicfeatures.DynamicGraphNavigator navGraphNavigator, androidx.navigation.NavigatorProvider navigatorProvider);
-    method public String? getModuleName();
-    method public int getProgressDestination();
-    method public void setModuleName(String?);
-    method public void setProgressDestination(int);
-    property public final String? moduleName;
-    property public final int progressDestination;
-  }
-
-  @androidx.navigation.Navigator.Name("include-dynamic") public final class DynamicIncludeGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
-    ctor public DynamicIncludeGraphNavigator(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.NavInflater navInflater, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
-    method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph createDestination();
-  }
-
-  public static final class DynamicIncludeGraphNavigator.DynamicIncludeNavGraph extends androidx.navigation.NavDestination {
-    method public String? getGraphPackage();
-    method public String? getGraphResourceName();
-    method public String? getModuleName();
-    method public void setGraphPackage(String?);
-    method public void setGraphResourceName(String?);
-    method public void setModuleName(String?);
-    property public final String? graphPackage;
-    property public final String? graphResourceName;
-    property public final String? moduleName;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DynamicIncludeNavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
-    ctor @Deprecated public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
-    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, String route, String moduleName, String graphResourceName);
-    method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph build();
-    method public String? getGraphPackage();
-    method public void setGraphPackage(String?);
-    property public final String? graphPackage;
-  }
-
-  public final class DynamicIncludeNavGraphBuilderKt {
-    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName);
-    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName);
-    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public class DynamicInstallManager {
-    ctor public DynamicInstallManager(android.content.Context context, com.google.android.play.core.splitinstall.SplitInstallManager splitInstallManager);
-  }
-
-  public final class DynamicInstallMonitor {
-    ctor public DynamicInstallMonitor();
-    method public void cancelInstall();
-    method public Exception? getException();
-    method public int getSessionId();
-    method public androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> getStatus();
-    method public boolean isInstallRequired();
-    property public final Exception? exception;
-    property public final boolean isInstallRequired;
-    property public final int sessionId;
-    property public final androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> status;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DynamicNavGraphBuilder extends androidx.navigation.NavGraphBuilder {
-    ctor @Deprecated public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, optional String? route);
-    method public String? getModuleName();
-    method public int getProgressDestination();
-    method public String? getProgressDestinationRoute();
-    method public void setModuleName(String?);
-    method public void setProgressDestination(int);
-    method public void setProgressDestinationRoute(String?);
-    property public final String? moduleName;
-    property public final int progressDestination;
-    property public final String? progressDestinationRoute;
-  }
-
-  public final class DynamicNavGraphBuilderKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method @Deprecated public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavControllerKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavHostKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-  }
-
-}
-
diff --git a/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_2.5.0-beta01.txt b/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_2.5.0-beta01.txt
deleted file mode 100644
index e4c37db..0000000
--- a/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_2.5.0-beta01.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.dynamicfeatures {
-
-  @androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
-    ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
-    method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
-  }
-
-  public static final class DynamicActivityNavigator.Destination extends androidx.navigation.ActivityNavigator.Destination {
-    ctor public DynamicActivityNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    ctor public DynamicActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination> activityNavigator);
-    method public String? getModuleName();
-    method public void setModuleName(String?);
-    property public final String? moduleName;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DynamicActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
-    ctor @Deprecated public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
-    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, String route);
-    method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination build();
-    method public String? getAction();
-    method public String? getActivityClassName();
-    method public android.net.Uri? getData();
-    method public String? getDataPattern();
-    method public String? getModuleName();
-    method public String? getTargetPackage();
-    method public void setAction(String?);
-    method public void setActivityClassName(String?);
-    method public void setData(android.net.Uri?);
-    method public void setDataPattern(String?);
-    method public void setModuleName(String?);
-    method public void setTargetPackage(String?);
-    property public final String? action;
-    property public final String? activityClassName;
-    property public final android.net.Uri? data;
-    property public final String? dataPattern;
-    property public final String? moduleName;
-    property public final String? targetPackage;
-  }
-
-  public final class DynamicActivityNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-  }
-
-  public final class DynamicExtras implements androidx.navigation.Navigator.Extras {
-    ctor public DynamicExtras(optional androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor, optional androidx.navigation.Navigator.Extras? destinationExtras);
-    ctor public DynamicExtras(optional androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor);
-    ctor public DynamicExtras();
-    method public androidx.navigation.Navigator.Extras? getDestinationExtras();
-    method public androidx.navigation.dynamicfeatures.DynamicInstallMonitor? getInstallMonitor();
-    property public final androidx.navigation.Navigator.Extras? destinationExtras;
-    property public final androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor;
-  }
-
-  @androidx.navigation.Navigator.Name("navigation") public final class DynamicGraphNavigator extends androidx.navigation.NavGraphNavigator {
-    ctor public DynamicGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
-    method public androidx.navigation.dynamicfeatures.DynamicGraphNavigator.DynamicNavGraph createDestination();
-    method public void installDefaultProgressDestination(kotlin.jvm.functions.Function0<? extends androidx.navigation.NavDestination> progressDestinationSupplier);
-  }
-
-  public static final class DynamicGraphNavigator.DynamicNavGraph extends androidx.navigation.NavGraph {
-    ctor public DynamicGraphNavigator.DynamicNavGraph(androidx.navigation.dynamicfeatures.DynamicGraphNavigator navGraphNavigator, androidx.navigation.NavigatorProvider navigatorProvider);
-    method public String? getModuleName();
-    method public int getProgressDestination();
-    method public void setModuleName(String?);
-    method public void setProgressDestination(int);
-    property public final String? moduleName;
-    property public final int progressDestination;
-  }
-
-  @androidx.navigation.Navigator.Name("include-dynamic") public final class DynamicIncludeGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
-    ctor public DynamicIncludeGraphNavigator(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.NavInflater navInflater, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
-    method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph createDestination();
-  }
-
-  public static final class DynamicIncludeGraphNavigator.DynamicIncludeNavGraph extends androidx.navigation.NavDestination {
-    method public String? getGraphPackage();
-    method public String? getGraphResourceName();
-    method public String? getModuleName();
-    method public void setGraphPackage(String?);
-    method public void setGraphResourceName(String?);
-    method public void setModuleName(String?);
-    property public final String? graphPackage;
-    property public final String? graphResourceName;
-    property public final String? moduleName;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DynamicIncludeNavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
-    ctor @Deprecated public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
-    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, String route, String moduleName, String graphResourceName);
-    method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph build();
-    method public String? getGraphPackage();
-    method public void setGraphPackage(String?);
-    property public final String? graphPackage;
-  }
-
-  public final class DynamicIncludeNavGraphBuilderKt {
-    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName);
-    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName);
-    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public class DynamicInstallManager {
-    ctor public DynamicInstallManager(android.content.Context context, com.google.android.play.core.splitinstall.SplitInstallManager splitInstallManager);
-  }
-
-  public final class DynamicInstallMonitor {
-    ctor public DynamicInstallMonitor();
-    method public void cancelInstall();
-    method public Exception? getException();
-    method public int getSessionId();
-    method public androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> getStatus();
-    method public boolean isInstallRequired();
-    property public final Exception? exception;
-    property public final boolean isInstallRequired;
-    property public final int sessionId;
-    property public final androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> status;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DynamicNavGraphBuilder extends androidx.navigation.NavGraphBuilder {
-    ctor @Deprecated public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, optional String? route);
-    method public String? getModuleName();
-    method public int getProgressDestination();
-    method public String? getProgressDestinationRoute();
-    method public void setModuleName(String?);
-    method public void setProgressDestination(int);
-    method public void setProgressDestinationRoute(String?);
-    property public final String? moduleName;
-    property public final int progressDestination;
-    property public final String? progressDestinationRoute;
-  }
-
-  public final class DynamicNavGraphBuilderKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method @Deprecated public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavControllerKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavHostKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-  }
-
-}
-
diff --git a/navigation/navigation-dynamic-features-runtime/api/res-2.5.0-beta01.txt b/navigation/navigation-dynamic-features-runtime/api/res-2.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/navigation/navigation-dynamic-features-runtime/api/res-2.5.0-beta01.txt
+++ /dev/null
diff --git a/navigation/navigation-dynamic-features-runtime/api/restricted_2.5.0-beta01.txt b/navigation/navigation-dynamic-features-runtime/api/restricted_2.5.0-beta01.txt
deleted file mode 100644
index e4c37db..0000000
--- a/navigation/navigation-dynamic-features-runtime/api/restricted_2.5.0-beta01.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.dynamicfeatures {
-
-  @androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
-    ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
-    method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
-  }
-
-  public static final class DynamicActivityNavigator.Destination extends androidx.navigation.ActivityNavigator.Destination {
-    ctor public DynamicActivityNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    ctor public DynamicActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination> activityNavigator);
-    method public String? getModuleName();
-    method public void setModuleName(String?);
-    property public final String? moduleName;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DynamicActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
-    ctor @Deprecated public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
-    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, String route);
-    method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination build();
-    method public String? getAction();
-    method public String? getActivityClassName();
-    method public android.net.Uri? getData();
-    method public String? getDataPattern();
-    method public String? getModuleName();
-    method public String? getTargetPackage();
-    method public void setAction(String?);
-    method public void setActivityClassName(String?);
-    method public void setData(android.net.Uri?);
-    method public void setDataPattern(String?);
-    method public void setModuleName(String?);
-    method public void setTargetPackage(String?);
-    property public final String? action;
-    property public final String? activityClassName;
-    property public final android.net.Uri? data;
-    property public final String? dataPattern;
-    property public final String? moduleName;
-    property public final String? targetPackage;
-  }
-
-  public final class DynamicActivityNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-  }
-
-  public final class DynamicExtras implements androidx.navigation.Navigator.Extras {
-    ctor public DynamicExtras(optional androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor, optional androidx.navigation.Navigator.Extras? destinationExtras);
-    ctor public DynamicExtras(optional androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor);
-    ctor public DynamicExtras();
-    method public androidx.navigation.Navigator.Extras? getDestinationExtras();
-    method public androidx.navigation.dynamicfeatures.DynamicInstallMonitor? getInstallMonitor();
-    property public final androidx.navigation.Navigator.Extras? destinationExtras;
-    property public final androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor;
-  }
-
-  @androidx.navigation.Navigator.Name("navigation") public final class DynamicGraphNavigator extends androidx.navigation.NavGraphNavigator {
-    ctor public DynamicGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
-    method public androidx.navigation.dynamicfeatures.DynamicGraphNavigator.DynamicNavGraph createDestination();
-    method public void installDefaultProgressDestination(kotlin.jvm.functions.Function0<? extends androidx.navigation.NavDestination> progressDestinationSupplier);
-  }
-
-  public static final class DynamicGraphNavigator.DynamicNavGraph extends androidx.navigation.NavGraph {
-    ctor public DynamicGraphNavigator.DynamicNavGraph(androidx.navigation.dynamicfeatures.DynamicGraphNavigator navGraphNavigator, androidx.navigation.NavigatorProvider navigatorProvider);
-    method public String? getModuleName();
-    method public int getProgressDestination();
-    method public void setModuleName(String?);
-    method public void setProgressDestination(int);
-    property public final String? moduleName;
-    property public final int progressDestination;
-  }
-
-  @androidx.navigation.Navigator.Name("include-dynamic") public final class DynamicIncludeGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
-    ctor public DynamicIncludeGraphNavigator(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.NavInflater navInflater, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
-    method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph createDestination();
-  }
-
-  public static final class DynamicIncludeGraphNavigator.DynamicIncludeNavGraph extends androidx.navigation.NavDestination {
-    method public String? getGraphPackage();
-    method public String? getGraphResourceName();
-    method public String? getModuleName();
-    method public void setGraphPackage(String?);
-    method public void setGraphResourceName(String?);
-    method public void setModuleName(String?);
-    property public final String? graphPackage;
-    property public final String? graphResourceName;
-    property public final String? moduleName;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DynamicIncludeNavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
-    ctor @Deprecated public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
-    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, String route, String moduleName, String graphResourceName);
-    method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph build();
-    method public String? getGraphPackage();
-    method public void setGraphPackage(String?);
-    property public final String? graphPackage;
-  }
-
-  public final class DynamicIncludeNavGraphBuilderKt {
-    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName);
-    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName);
-    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public class DynamicInstallManager {
-    ctor public DynamicInstallManager(android.content.Context context, com.google.android.play.core.splitinstall.SplitInstallManager splitInstallManager);
-  }
-
-  public final class DynamicInstallMonitor {
-    ctor public DynamicInstallMonitor();
-    method public void cancelInstall();
-    method public Exception? getException();
-    method public int getSessionId();
-    method public androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> getStatus();
-    method public boolean isInstallRequired();
-    property public final Exception? exception;
-    property public final boolean isInstallRequired;
-    property public final int sessionId;
-    property public final androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> status;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DynamicNavGraphBuilder extends androidx.navigation.NavGraphBuilder {
-    ctor @Deprecated public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
-    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, optional String? route);
-    method public String? getModuleName();
-    method public int getProgressDestination();
-    method public String? getProgressDestinationRoute();
-    method public void setModuleName(String?);
-    method public void setProgressDestination(int);
-    method public void setProgressDestinationRoute(String?);
-    property public final String? moduleName;
-    property public final int progressDestination;
-    property public final String? progressDestinationRoute;
-  }
-
-  public final class DynamicNavGraphBuilderKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method @Deprecated public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavControllerKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavHostKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
-  }
-
-}
-
diff --git a/navigation/navigation-fragment-ktx/api/2.5.0-beta01.txt b/navigation/navigation-fragment-ktx/api/2.5.0-beta01.txt
deleted file mode 100644
index e6f50d0..0000000
--- a/navigation/navigation-fragment-ktx/api/2.5.0-beta01.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 4.0
diff --git a/navigation/navigation-fragment-ktx/api/public_plus_experimental_2.5.0-beta01.txt b/navigation/navigation-fragment-ktx/api/public_plus_experimental_2.5.0-beta01.txt
deleted file mode 100644
index e6f50d0..0000000
--- a/navigation/navigation-fragment-ktx/api/public_plus_experimental_2.5.0-beta01.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 4.0
diff --git a/navigation/navigation-fragment-ktx/api/res-2.5.0-beta01.txt b/navigation/navigation-fragment-ktx/api/res-2.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/navigation/navigation-fragment-ktx/api/res-2.5.0-beta01.txt
+++ /dev/null
diff --git a/navigation/navigation-fragment-ktx/api/restricted_2.5.0-beta01.txt b/navigation/navigation-fragment-ktx/api/restricted_2.5.0-beta01.txt
deleted file mode 100644
index e6f50d0..0000000
--- a/navigation/navigation-fragment-ktx/api/restricted_2.5.0-beta01.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 4.0
diff --git a/navigation/navigation-fragment/api/2.5.0-beta01.txt b/navigation/navigation-fragment/api/2.5.0-beta01.txt
deleted file mode 100644
index 52fc882..0000000
--- a/navigation/navigation-fragment/api/2.5.0-beta01.txt
+++ /dev/null
@@ -1,125 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation {
-
-  public final class NavGraphViewModelLazyKt {
-    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, String navGraphRoute, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, String navGraphRoute, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-  }
-
-}
-
-package androidx.navigation.fragment {
-
-  public abstract class AbstractListDetailFragment extends androidx.fragment.app.Fragment {
-    ctor public AbstractListDetailFragment();
-    method public final androidx.navigation.fragment.NavHostFragment getDetailPaneNavHostFragment();
-    method public final androidx.slidingpanelayout.widget.SlidingPaneLayout getSlidingPaneLayout();
-    method public androidx.navigation.fragment.NavHostFragment onCreateDetailPaneNavHostFragment();
-    method public abstract android.view.View onCreateListPaneView(android.view.LayoutInflater inflater, android.view.ViewGroup? container, android.os.Bundle? savedInstanceState);
-    method @CallSuper public final android.view.View onCreateView(android.view.LayoutInflater inflater, android.view.ViewGroup? container, android.os.Bundle? savedInstanceState);
-    method public void onListPaneViewCreated(android.view.View view, android.os.Bundle? savedInstanceState);
-    method @CallSuper public final void onViewCreated(android.view.View view, android.os.Bundle? savedInstanceState);
-    property public final androidx.navigation.fragment.NavHostFragment detailPaneNavHostFragment;
-    property public final androidx.slidingpanelayout.widget.SlidingPaneLayout slidingPaneLayout;
-  }
-
-  @androidx.navigation.Navigator.Name("dialog") public final class DialogFragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
-    ctor public DialogFragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager);
-    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination createDestination();
-  }
-
-  @androidx.navigation.NavDestination.ClassType(DialogFragment::class) public static class DialogFragmentNavigator.Destination extends androidx.navigation.NavDestination implements androidx.navigation.FloatingWindow {
-    ctor public DialogFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.DialogFragmentNavigator.Destination> fragmentNavigator);
-    ctor public DialogFragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    method public final String getClassName();
-    method public final androidx.navigation.fragment.DialogFragmentNavigator.Destination setClassName(String className);
-    property public final String className;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
-    ctor @Deprecated public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
-    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
-    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
-  }
-
-  public final class DialogFragmentNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-  }
-
-  public final class FragmentKt {
-    method public static androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment);
-  }
-
-  public final class FragmentNavArgsLazyKt {
-    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args>! navArgs(androidx.fragment.app.Fragment);
-  }
-
-  @androidx.navigation.Navigator.Name("fragment") public class FragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor public FragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, int containerId);
-    method public androidx.navigation.fragment.FragmentNavigator.Destination createDestination();
-    method @Deprecated public androidx.fragment.app.Fragment instantiateFragment(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, String className, android.os.Bundle? args);
-  }
-
-  @androidx.navigation.NavDestination.ClassType(Fragment::class) public static class FragmentNavigator.Destination extends androidx.navigation.NavDestination {
-    ctor public FragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> fragmentNavigator);
-    ctor public FragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    method public final String getClassName();
-    method public final androidx.navigation.fragment.FragmentNavigator.Destination setClassName(String className);
-    property public final String className;
-  }
-
-  public static final class FragmentNavigator.Extras implements androidx.navigation.Navigator.Extras {
-    method public java.util.Map<android.view.View,java.lang.String> getSharedElements();
-    property public final java.util.Map<android.view.View,java.lang.String> sharedElements;
-  }
-
-  public static final class FragmentNavigator.Extras.Builder {
-    ctor public FragmentNavigator.Extras.Builder();
-    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElement(android.view.View sharedElement, String name);
-    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElements(java.util.Map<android.view.View,java.lang.String> sharedElements);
-    method public androidx.navigation.fragment.FragmentNavigator.Extras build();
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor @Deprecated public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
-    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
-    method public androidx.navigation.fragment.FragmentNavigator.Destination build();
-  }
-
-  public final class FragmentNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-  }
-
-  public final class FragmentNavigatorExtrasKt {
-    method public static androidx.navigation.fragment.FragmentNavigator.Extras FragmentNavigatorExtras(kotlin.Pair<? extends android.view.View,java.lang.String>... sharedElements);
-  }
-
-  public class NavHostFragment extends androidx.fragment.app.Fragment implements androidx.navigation.NavHost {
-    ctor public NavHostFragment();
-    method public static final androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
-    method public static final androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId);
-    method @Deprecated protected androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> createFragmentNavigator();
-    method public static final androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment fragment);
-    method public final androidx.navigation.NavController getNavController();
-    method @Deprecated @CallSuper protected void onCreateNavController(androidx.navigation.NavController navController);
-    method @CallSuper protected void onCreateNavHostController(androidx.navigation.NavHostController navHostController);
-    property public final androidx.navigation.NavController navController;
-    field public static final androidx.navigation.fragment.NavHostFragment.Companion Companion;
-  }
-
-  public static final class NavHostFragment.Companion {
-    method public androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
-    method public androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId);
-    method public androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment fragment);
-  }
-
-}
-
diff --git a/navigation/navigation-fragment/api/public_plus_experimental_2.5.0-beta01.txt b/navigation/navigation-fragment/api/public_plus_experimental_2.5.0-beta01.txt
deleted file mode 100644
index 52fc882..0000000
--- a/navigation/navigation-fragment/api/public_plus_experimental_2.5.0-beta01.txt
+++ /dev/null
@@ -1,125 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation {
-
-  public final class NavGraphViewModelLazyKt {
-    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, String navGraphRoute, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, String navGraphRoute, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-  }
-
-}
-
-package androidx.navigation.fragment {
-
-  public abstract class AbstractListDetailFragment extends androidx.fragment.app.Fragment {
-    ctor public AbstractListDetailFragment();
-    method public final androidx.navigation.fragment.NavHostFragment getDetailPaneNavHostFragment();
-    method public final androidx.slidingpanelayout.widget.SlidingPaneLayout getSlidingPaneLayout();
-    method public androidx.navigation.fragment.NavHostFragment onCreateDetailPaneNavHostFragment();
-    method public abstract android.view.View onCreateListPaneView(android.view.LayoutInflater inflater, android.view.ViewGroup? container, android.os.Bundle? savedInstanceState);
-    method @CallSuper public final android.view.View onCreateView(android.view.LayoutInflater inflater, android.view.ViewGroup? container, android.os.Bundle? savedInstanceState);
-    method public void onListPaneViewCreated(android.view.View view, android.os.Bundle? savedInstanceState);
-    method @CallSuper public final void onViewCreated(android.view.View view, android.os.Bundle? savedInstanceState);
-    property public final androidx.navigation.fragment.NavHostFragment detailPaneNavHostFragment;
-    property public final androidx.slidingpanelayout.widget.SlidingPaneLayout slidingPaneLayout;
-  }
-
-  @androidx.navigation.Navigator.Name("dialog") public final class DialogFragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
-    ctor public DialogFragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager);
-    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination createDestination();
-  }
-
-  @androidx.navigation.NavDestination.ClassType(DialogFragment::class) public static class DialogFragmentNavigator.Destination extends androidx.navigation.NavDestination implements androidx.navigation.FloatingWindow {
-    ctor public DialogFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.DialogFragmentNavigator.Destination> fragmentNavigator);
-    ctor public DialogFragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    method public final String getClassName();
-    method public final androidx.navigation.fragment.DialogFragmentNavigator.Destination setClassName(String className);
-    property public final String className;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
-    ctor @Deprecated public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
-    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
-    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
-  }
-
-  public final class DialogFragmentNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-  }
-
-  public final class FragmentKt {
-    method public static androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment);
-  }
-
-  public final class FragmentNavArgsLazyKt {
-    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args>! navArgs(androidx.fragment.app.Fragment);
-  }
-
-  @androidx.navigation.Navigator.Name("fragment") public class FragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor public FragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, int containerId);
-    method public androidx.navigation.fragment.FragmentNavigator.Destination createDestination();
-    method @Deprecated public androidx.fragment.app.Fragment instantiateFragment(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, String className, android.os.Bundle? args);
-  }
-
-  @androidx.navigation.NavDestination.ClassType(Fragment::class) public static class FragmentNavigator.Destination extends androidx.navigation.NavDestination {
-    ctor public FragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> fragmentNavigator);
-    ctor public FragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    method public final String getClassName();
-    method public final androidx.navigation.fragment.FragmentNavigator.Destination setClassName(String className);
-    property public final String className;
-  }
-
-  public static final class FragmentNavigator.Extras implements androidx.navigation.Navigator.Extras {
-    method public java.util.Map<android.view.View,java.lang.String> getSharedElements();
-    property public final java.util.Map<android.view.View,java.lang.String> sharedElements;
-  }
-
-  public static final class FragmentNavigator.Extras.Builder {
-    ctor public FragmentNavigator.Extras.Builder();
-    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElement(android.view.View sharedElement, String name);
-    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElements(java.util.Map<android.view.View,java.lang.String> sharedElements);
-    method public androidx.navigation.fragment.FragmentNavigator.Extras build();
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor @Deprecated public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
-    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
-    method public androidx.navigation.fragment.FragmentNavigator.Destination build();
-  }
-
-  public final class FragmentNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-  }
-
-  public final class FragmentNavigatorExtrasKt {
-    method public static androidx.navigation.fragment.FragmentNavigator.Extras FragmentNavigatorExtras(kotlin.Pair<? extends android.view.View,java.lang.String>... sharedElements);
-  }
-
-  public class NavHostFragment extends androidx.fragment.app.Fragment implements androidx.navigation.NavHost {
-    ctor public NavHostFragment();
-    method public static final androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
-    method public static final androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId);
-    method @Deprecated protected androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> createFragmentNavigator();
-    method public static final androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment fragment);
-    method public final androidx.navigation.NavController getNavController();
-    method @Deprecated @CallSuper protected void onCreateNavController(androidx.navigation.NavController navController);
-    method @CallSuper protected void onCreateNavHostController(androidx.navigation.NavHostController navHostController);
-    property public final androidx.navigation.NavController navController;
-    field public static final androidx.navigation.fragment.NavHostFragment.Companion Companion;
-  }
-
-  public static final class NavHostFragment.Companion {
-    method public androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
-    method public androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId);
-    method public androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment fragment);
-  }
-
-}
-
diff --git a/navigation/navigation-fragment/api/res-2.5.0-beta01.txt b/navigation/navigation-fragment/api/res-2.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/navigation/navigation-fragment/api/res-2.5.0-beta01.txt
+++ /dev/null
diff --git a/navigation/navigation-fragment/api/restricted_2.5.0-beta01.txt b/navigation/navigation-fragment/api/restricted_2.5.0-beta01.txt
deleted file mode 100644
index 52fc882..0000000
--- a/navigation/navigation-fragment/api/restricted_2.5.0-beta01.txt
+++ /dev/null
@@ -1,125 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation {
-
-  public final class NavGraphViewModelLazyKt {
-    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, String navGraphRoute, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<? extends VM>! navGraphViewModels(androidx.fragment.app.Fragment, String navGraphRoute, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
-  }
-
-}
-
-package androidx.navigation.fragment {
-
-  public abstract class AbstractListDetailFragment extends androidx.fragment.app.Fragment {
-    ctor public AbstractListDetailFragment();
-    method public final androidx.navigation.fragment.NavHostFragment getDetailPaneNavHostFragment();
-    method public final androidx.slidingpanelayout.widget.SlidingPaneLayout getSlidingPaneLayout();
-    method public androidx.navigation.fragment.NavHostFragment onCreateDetailPaneNavHostFragment();
-    method public abstract android.view.View onCreateListPaneView(android.view.LayoutInflater inflater, android.view.ViewGroup? container, android.os.Bundle? savedInstanceState);
-    method @CallSuper public final android.view.View onCreateView(android.view.LayoutInflater inflater, android.view.ViewGroup? container, android.os.Bundle? savedInstanceState);
-    method public void onListPaneViewCreated(android.view.View view, android.os.Bundle? savedInstanceState);
-    method @CallSuper public final void onViewCreated(android.view.View view, android.os.Bundle? savedInstanceState);
-    property public final androidx.navigation.fragment.NavHostFragment detailPaneNavHostFragment;
-    property public final androidx.slidingpanelayout.widget.SlidingPaneLayout slidingPaneLayout;
-  }
-
-  @androidx.navigation.Navigator.Name("dialog") public final class DialogFragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
-    ctor public DialogFragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager);
-    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination createDestination();
-  }
-
-  @androidx.navigation.NavDestination.ClassType(DialogFragment::class) public static class DialogFragmentNavigator.Destination extends androidx.navigation.NavDestination implements androidx.navigation.FloatingWindow {
-    ctor public DialogFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.DialogFragmentNavigator.Destination> fragmentNavigator);
-    ctor public DialogFragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    method public final String getClassName();
-    method public final androidx.navigation.fragment.DialogFragmentNavigator.Destination setClassName(String className);
-    property public final String className;
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
-    ctor @Deprecated public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
-    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
-    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
-  }
-
-  public final class DialogFragmentNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route);
-    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-  }
-
-  public final class FragmentKt {
-    method public static androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment);
-  }
-
-  public final class FragmentNavArgsLazyKt {
-    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args>! navArgs(androidx.fragment.app.Fragment);
-  }
-
-  @androidx.navigation.Navigator.Name("fragment") public class FragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor public FragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, int containerId);
-    method public androidx.navigation.fragment.FragmentNavigator.Destination createDestination();
-    method @Deprecated public androidx.fragment.app.Fragment instantiateFragment(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, String className, android.os.Bundle? args);
-  }
-
-  @androidx.navigation.NavDestination.ClassType(Fragment::class) public static class FragmentNavigator.Destination extends androidx.navigation.NavDestination {
-    ctor public FragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> fragmentNavigator);
-    ctor public FragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    method public final String getClassName();
-    method public final androidx.navigation.fragment.FragmentNavigator.Destination setClassName(String className);
-    property public final String className;
-  }
-
-  public static final class FragmentNavigator.Extras implements androidx.navigation.Navigator.Extras {
-    method public java.util.Map<android.view.View,java.lang.String> getSharedElements();
-    property public final java.util.Map<android.view.View,java.lang.String> sharedElements;
-  }
-
-  public static final class FragmentNavigator.Extras.Builder {
-    ctor public FragmentNavigator.Extras.Builder();
-    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElement(android.view.View sharedElement, String name);
-    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElements(java.util.Map<android.view.View,java.lang.String> sharedElements);
-    method public androidx.navigation.fragment.FragmentNavigator.Extras build();
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
-    ctor @Deprecated public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
-    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
-    method public androidx.navigation.fragment.FragmentNavigator.Destination build();
-  }
-
-  public final class FragmentNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id);
-    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route);
-    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,? extends kotlin.Unit> builder);
-  }
-
-  public final class FragmentNavigatorExtrasKt {
-    method public static androidx.navigation.fragment.FragmentNavigator.Extras FragmentNavigatorExtras(kotlin.Pair<? extends android.view.View,java.lang.String>... sharedElements);
-  }
-
-  public class NavHostFragment extends androidx.fragment.app.Fragment implements androidx.navigation.NavHost {
-    ctor public NavHostFragment();
-    method public static final androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
-    method public static final androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId);
-    method @Deprecated protected androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> createFragmentNavigator();
-    method public static final androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment fragment);
-    method public final androidx.navigation.NavController getNavController();
-    method @Deprecated @CallSuper protected void onCreateNavController(androidx.navigation.NavController navController);
-    method @CallSuper protected void onCreateNavHostController(androidx.navigation.NavHostController navHostController);
-    property public final androidx.navigation.NavController navController;
-    field public static final androidx.navigation.fragment.NavHostFragment.Companion Companion;
-  }
-
-  public static final class NavHostFragment.Companion {
-    method public androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
-    method public androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId);
-    method public androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment fragment);
-  }
-
-}
-
diff --git a/navigation/navigation-runtime-ktx/api/2.5.0-beta01.txt b/navigation/navigation-runtime-ktx/api/2.5.0-beta01.txt
deleted file mode 100644
index e6f50d0..0000000
--- a/navigation/navigation-runtime-ktx/api/2.5.0-beta01.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 4.0
diff --git a/navigation/navigation-runtime-ktx/api/public_plus_experimental_2.5.0-beta01.txt b/navigation/navigation-runtime-ktx/api/public_plus_experimental_2.5.0-beta01.txt
deleted file mode 100644
index e6f50d0..0000000
--- a/navigation/navigation-runtime-ktx/api/public_plus_experimental_2.5.0-beta01.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 4.0
diff --git a/navigation/navigation-runtime-ktx/api/res-2.5.0-beta01.txt b/navigation/navigation-runtime-ktx/api/res-2.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/navigation/navigation-runtime-ktx/api/res-2.5.0-beta01.txt
+++ /dev/null
diff --git a/navigation/navigation-runtime-ktx/api/restricted_2.5.0-beta01.txt b/navigation/navigation-runtime-ktx/api/restricted_2.5.0-beta01.txt
deleted file mode 100644
index e6f50d0..0000000
--- a/navigation/navigation-runtime-ktx/api/restricted_2.5.0-beta01.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 4.0
diff --git a/navigation/navigation-runtime/api/2.5.0-beta01.txt b/navigation/navigation-runtime/api/2.5.0-beta01.txt
deleted file mode 100644
index 7f117bb..0000000
--- a/navigation/navigation-runtime/api/2.5.0-beta01.txt
+++ /dev/null
@@ -1,224 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation {
-
-  public final class ActivityKt {
-    method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int viewId);
-  }
-
-  public final class ActivityNavArgsLazyKt {
-    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args>! navArgs(android.app.Activity);
-  }
-
-  @androidx.navigation.Navigator.Name("activity") public class ActivityNavigator extends androidx.navigation.Navigator<androidx.navigation.ActivityNavigator.Destination> {
-    ctor public ActivityNavigator(android.content.Context context);
-    method public static final void applyPopAnimationsToPendingTransition(android.app.Activity activity);
-    method public androidx.navigation.ActivityNavigator.Destination createDestination();
-    method public androidx.navigation.NavDestination? navigate(androidx.navigation.ActivityNavigator.Destination destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    field public static final androidx.navigation.ActivityNavigator.Companion Companion;
-  }
-
-  public static final class ActivityNavigator.Companion {
-    method public void applyPopAnimationsToPendingTransition(android.app.Activity activity);
-  }
-
-  @androidx.navigation.NavDestination.ClassType(Activity::class) public static class ActivityNavigator.Destination extends androidx.navigation.NavDestination {
-    ctor public ActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination> activityNavigator);
-    ctor public ActivityNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    method public final String? getAction();
-    method public final android.content.ComponentName? getComponent();
-    method public final android.net.Uri? getData();
-    method public final String? getDataPattern();
-    method public final android.content.Intent? getIntent();
-    method public final String? getTargetPackage();
-    method public final androidx.navigation.ActivityNavigator.Destination setAction(String? action);
-    method public final androidx.navigation.ActivityNavigator.Destination setComponentName(android.content.ComponentName? name);
-    method public final androidx.navigation.ActivityNavigator.Destination setData(android.net.Uri? data);
-    method public final androidx.navigation.ActivityNavigator.Destination setDataPattern(String? dataPattern);
-    method public final androidx.navigation.ActivityNavigator.Destination setIntent(android.content.Intent? intent);
-    method public final androidx.navigation.ActivityNavigator.Destination setTargetPackage(String? packageName);
-    property public final String? action;
-    property public final android.content.ComponentName? component;
-    property public final android.net.Uri? data;
-    property public final String? dataPattern;
-    property public final android.content.Intent? intent;
-    property public final String? targetPackage;
-  }
-
-  public static final class ActivityNavigator.Extras implements androidx.navigation.Navigator.Extras {
-    method public androidx.core.app.ActivityOptionsCompat? getActivityOptions();
-    method public int getFlags();
-    property public final androidx.core.app.ActivityOptionsCompat? activityOptions;
-    property public final int flags;
-  }
-
-  public static final class ActivityNavigator.Extras.Builder {
-    ctor public ActivityNavigator.Extras.Builder();
-    method public androidx.navigation.ActivityNavigator.Extras.Builder addFlags(int flags);
-    method public androidx.navigation.ActivityNavigator.Extras build();
-    method public androidx.navigation.ActivityNavigator.Extras.Builder setActivityOptions(androidx.core.app.ActivityOptionsCompat activityOptions);
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
-    ctor @Deprecated public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
-    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, String route);
-    method public androidx.navigation.ActivityNavigator.Destination build();
-    method public String? getAction();
-    method public kotlin.reflect.KClass<? extends android.app.Activity>? getActivityClass();
-    method public android.net.Uri? getData();
-    method public String? getDataPattern();
-    method public String? getTargetPackage();
-    method public void setAction(String?);
-    method public void setActivityClass(kotlin.reflect.KClass<? extends android.app.Activity>?);
-    method public void setData(android.net.Uri?);
-    method public void setDataPattern(String?);
-    method public void setTargetPackage(String?);
-    property public final String? action;
-    property public final kotlin.reflect.KClass<? extends android.app.Activity>? activityClass;
-    property public final android.net.Uri? data;
-    property public final String? dataPattern;
-    property public final String? targetPackage;
-  }
-
-  public final class ActivityNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline void activity(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-  }
-
-  public final class ActivityNavigatorExtrasKt {
-    method public static androidx.navigation.ActivityNavigator.Extras ActivityNavigatorExtras(optional androidx.core.app.ActivityOptionsCompat? activityOptions, optional int flags);
-  }
-
-  public class NavController {
-    ctor public NavController(android.content.Context context);
-    method public void addOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener listener);
-    method @MainThread public final boolean clearBackStack(String route);
-    method @MainThread public final boolean clearBackStack(@IdRes int destinationId);
-    method public androidx.navigation.NavDeepLinkBuilder createDeepLink();
-    method public androidx.navigation.NavBackStackEntry getBackStackEntry(@IdRes int destinationId);
-    method public final androidx.navigation.NavBackStackEntry getBackStackEntry(String route);
-    method public androidx.navigation.NavBackStackEntry? getCurrentBackStackEntry();
-    method public final kotlinx.coroutines.flow.Flow<androidx.navigation.NavBackStackEntry> getCurrentBackStackEntryFlow();
-    method public androidx.navigation.NavDestination? getCurrentDestination();
-    method @MainThread public androidx.navigation.NavGraph getGraph();
-    method public androidx.navigation.NavInflater getNavInflater();
-    method public androidx.navigation.NavigatorProvider getNavigatorProvider();
-    method public androidx.navigation.NavBackStackEntry? getPreviousBackStackEntry();
-    method public androidx.lifecycle.ViewModelStoreOwner getViewModelStoreOwner(@IdRes int navGraphId);
-    method public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getVisibleEntries();
-    method @MainThread public boolean handleDeepLink(android.content.Intent? intent);
-    method @MainThread public void navigate(@IdRes int resId);
-    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args);
-    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions);
-    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method @MainThread public void navigate(android.net.Uri deepLink);
-    method @MainThread public void navigate(android.net.Uri deepLink, androidx.navigation.NavOptions? navOptions);
-    method @MainThread public void navigate(android.net.Uri deepLink, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request);
-    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request, androidx.navigation.NavOptions? navOptions);
-    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method @MainThread public void navigate(androidx.navigation.NavDirections directions);
-    method @MainThread public void navigate(androidx.navigation.NavDirections directions, androidx.navigation.NavOptions? navOptions);
-    method @MainThread public void navigate(androidx.navigation.NavDirections directions, androidx.navigation.Navigator.Extras navigatorExtras);
-    method public final void navigate(String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> builder);
-    method public final void navigate(String route, optional androidx.navigation.NavOptions? navOptions, optional androidx.navigation.Navigator.Extras? navigatorExtras);
-    method public final void navigate(String route, optional androidx.navigation.NavOptions? navOptions);
-    method public final void navigate(String route);
-    method @MainThread public boolean navigateUp();
-    method @MainThread public boolean popBackStack();
-    method @MainThread public boolean popBackStack(@IdRes int destinationId, boolean inclusive);
-    method @MainThread public boolean popBackStack(@IdRes int destinationId, boolean inclusive, boolean saveState);
-    method @MainThread public final boolean popBackStack(String route, boolean inclusive, optional boolean saveState);
-    method @MainThread public final boolean popBackStack(String route, boolean inclusive);
-    method public void removeOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener listener);
-    method @CallSuper public void restoreState(android.os.Bundle? navState);
-    method @CallSuper public android.os.Bundle? saveState();
-    method @CallSuper @MainThread public void setGraph(androidx.navigation.NavGraph);
-    method @CallSuper @MainThread public void setGraph(@NavigationRes int graphResId);
-    method @CallSuper @MainThread public void setGraph(@NavigationRes int graphResId, android.os.Bundle? startDestinationArgs);
-    method @CallSuper @MainThread public void setGraph(androidx.navigation.NavGraph graph, android.os.Bundle? startDestinationArgs);
-    property public androidx.navigation.NavBackStackEntry? currentBackStackEntry;
-    property public final kotlinx.coroutines.flow.Flow<androidx.navigation.NavBackStackEntry> currentBackStackEntryFlow;
-    property public androidx.navigation.NavDestination? currentDestination;
-    property @MainThread public androidx.navigation.NavGraph graph;
-    property public androidx.navigation.NavInflater navInflater;
-    property public androidx.navigation.NavigatorProvider navigatorProvider;
-    property public androidx.navigation.NavBackStackEntry? previousBackStackEntry;
-    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> visibleEntries;
-    field public static final androidx.navigation.NavController.Companion Companion;
-    field public static final String KEY_DEEP_LINK_INTENT = "android-support-nav:controller:deepLinkIntent";
-  }
-
-  public static final class NavController.Companion {
-  }
-
-  public static fun interface NavController.OnDestinationChangedListener {
-    method public void onDestinationChanged(androidx.navigation.NavController controller, androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
-  }
-
-  public final class NavControllerKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavDeepLinkBuilder {
-    ctor public NavDeepLinkBuilder(android.content.Context context);
-    method public androidx.navigation.NavDeepLinkBuilder addDestination(@IdRes int destId, optional android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder addDestination(@IdRes int destId);
-    method public androidx.navigation.NavDeepLinkBuilder addDestination(String route, optional android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder addDestination(String route);
-    method public android.app.PendingIntent createPendingIntent();
-    method public androidx.core.app.TaskStackBuilder createTaskStackBuilder();
-    method public androidx.navigation.NavDeepLinkBuilder setArguments(android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder setComponentName(Class<? extends android.app.Activity> activityClass);
-    method public androidx.navigation.NavDeepLinkBuilder setComponentName(android.content.ComponentName componentName);
-    method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int destId, optional android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int destId);
-    method public androidx.navigation.NavDeepLinkBuilder setDestination(String destRoute, optional android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder setDestination(String destRoute);
-    method public androidx.navigation.NavDeepLinkBuilder setGraph(@NavigationRes int navGraphId);
-    method public androidx.navigation.NavDeepLinkBuilder setGraph(androidx.navigation.NavGraph navGraph);
-  }
-
-  public interface NavHost {
-    method public androidx.navigation.NavController getNavController();
-    property public abstract androidx.navigation.NavController navController;
-  }
-
-  public class NavHostController extends androidx.navigation.NavController {
-    ctor public NavHostController(android.content.Context context);
-    method public final void enableOnBackPressed(boolean enabled);
-    method public final void setLifecycleOwner(androidx.lifecycle.LifecycleOwner owner);
-    method public final void setOnBackPressedDispatcher(androidx.activity.OnBackPressedDispatcher dispatcher);
-    method public final void setViewModelStore(androidx.lifecycle.ViewModelStore viewModelStore);
-  }
-
-  public final class NavHostKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavInflater {
-    ctor public NavInflater(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider);
-    method public androidx.navigation.NavGraph inflate(@NavigationRes int graphResId);
-    field public static final androidx.navigation.NavInflater.Companion Companion;
-  }
-
-  public static final class NavInflater.Companion {
-  }
-
-  public final class Navigation {
-    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int resId, optional android.os.Bundle? args);
-    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int resId);
-    method public static android.view.View.OnClickListener createNavigateOnClickListener(androidx.navigation.NavDirections directions);
-    method public static androidx.navigation.NavController findNavController(android.app.Activity activity, @IdRes int viewId);
-    method public static androidx.navigation.NavController findNavController(android.view.View view);
-    method public static void setViewNavController(android.view.View view, androidx.navigation.NavController? controller);
-    field public static final androidx.navigation.Navigation INSTANCE;
-  }
-
-  public final class ViewKt {
-    method public static androidx.navigation.NavController findNavController(android.view.View);
-  }
-
-}
-
diff --git a/navigation/navigation-runtime/api/public_plus_experimental_2.5.0-beta01.txt b/navigation/navigation-runtime/api/public_plus_experimental_2.5.0-beta01.txt
deleted file mode 100644
index 70ea8db..0000000
--- a/navigation/navigation-runtime/api/public_plus_experimental_2.5.0-beta01.txt
+++ /dev/null
@@ -1,229 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation {
-
-  public final class ActivityKt {
-    method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int viewId);
-  }
-
-  public final class ActivityNavArgsLazyKt {
-    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args>! navArgs(android.app.Activity);
-  }
-
-  @androidx.navigation.Navigator.Name("activity") public class ActivityNavigator extends androidx.navigation.Navigator<androidx.navigation.ActivityNavigator.Destination> {
-    ctor public ActivityNavigator(android.content.Context context);
-    method public static final void applyPopAnimationsToPendingTransition(android.app.Activity activity);
-    method public androidx.navigation.ActivityNavigator.Destination createDestination();
-    method public androidx.navigation.NavDestination? navigate(androidx.navigation.ActivityNavigator.Destination destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    field public static final androidx.navigation.ActivityNavigator.Companion Companion;
-  }
-
-  public static final class ActivityNavigator.Companion {
-    method public void applyPopAnimationsToPendingTransition(android.app.Activity activity);
-  }
-
-  @androidx.navigation.NavDestination.ClassType(Activity::class) public static class ActivityNavigator.Destination extends androidx.navigation.NavDestination {
-    ctor public ActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination> activityNavigator);
-    ctor public ActivityNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    method public final String? getAction();
-    method public final android.content.ComponentName? getComponent();
-    method public final android.net.Uri? getData();
-    method public final String? getDataPattern();
-    method public final android.content.Intent? getIntent();
-    method public final String? getTargetPackage();
-    method public final androidx.navigation.ActivityNavigator.Destination setAction(String? action);
-    method public final androidx.navigation.ActivityNavigator.Destination setComponentName(android.content.ComponentName? name);
-    method public final androidx.navigation.ActivityNavigator.Destination setData(android.net.Uri? data);
-    method public final androidx.navigation.ActivityNavigator.Destination setDataPattern(String? dataPattern);
-    method public final androidx.navigation.ActivityNavigator.Destination setIntent(android.content.Intent? intent);
-    method public final androidx.navigation.ActivityNavigator.Destination setTargetPackage(String? packageName);
-    property public final String? action;
-    property public final android.content.ComponentName? component;
-    property public final android.net.Uri? data;
-    property public final String? dataPattern;
-    property public final android.content.Intent? intent;
-    property public final String? targetPackage;
-  }
-
-  public static final class ActivityNavigator.Extras implements androidx.navigation.Navigator.Extras {
-    method public androidx.core.app.ActivityOptionsCompat? getActivityOptions();
-    method public int getFlags();
-    property public final androidx.core.app.ActivityOptionsCompat? activityOptions;
-    property public final int flags;
-  }
-
-  public static final class ActivityNavigator.Extras.Builder {
-    ctor public ActivityNavigator.Extras.Builder();
-    method public androidx.navigation.ActivityNavigator.Extras.Builder addFlags(int flags);
-    method public androidx.navigation.ActivityNavigator.Extras build();
-    method public androidx.navigation.ActivityNavigator.Extras.Builder setActivityOptions(androidx.core.app.ActivityOptionsCompat activityOptions);
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
-    ctor @Deprecated public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
-    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, String route);
-    method public androidx.navigation.ActivityNavigator.Destination build();
-    method public String? getAction();
-    method public kotlin.reflect.KClass<? extends android.app.Activity>? getActivityClass();
-    method public android.net.Uri? getData();
-    method public String? getDataPattern();
-    method public String? getTargetPackage();
-    method public void setAction(String?);
-    method public void setActivityClass(kotlin.reflect.KClass<? extends android.app.Activity>?);
-    method public void setData(android.net.Uri?);
-    method public void setDataPattern(String?);
-    method public void setTargetPackage(String?);
-    property public final String? action;
-    property public final kotlin.reflect.KClass<? extends android.app.Activity>? activityClass;
-    property public final android.net.Uri? data;
-    property public final String? dataPattern;
-    property public final String? targetPackage;
-  }
-
-  public final class ActivityNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline void activity(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-  }
-
-  public final class ActivityNavigatorExtrasKt {
-    method public static androidx.navigation.ActivityNavigator.Extras ActivityNavigatorExtras(optional androidx.core.app.ActivityOptionsCompat? activityOptions, optional int flags);
-  }
-
-  public class NavController {
-    ctor public NavController(android.content.Context context);
-    method public void addOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener listener);
-    method @MainThread public final boolean clearBackStack(String route);
-    method @MainThread public final boolean clearBackStack(@IdRes int destinationId);
-    method public androidx.navigation.NavDeepLinkBuilder createDeepLink();
-    method @androidx.navigation.NavDeepLinkSaveStateControl public static final void enableDeepLinkSaveState(boolean saveState);
-    method public androidx.navigation.NavBackStackEntry getBackStackEntry(@IdRes int destinationId);
-    method public final androidx.navigation.NavBackStackEntry getBackStackEntry(String route);
-    method public androidx.navigation.NavBackStackEntry? getCurrentBackStackEntry();
-    method public final kotlinx.coroutines.flow.Flow<androidx.navigation.NavBackStackEntry> getCurrentBackStackEntryFlow();
-    method public androidx.navigation.NavDestination? getCurrentDestination();
-    method @MainThread public androidx.navigation.NavGraph getGraph();
-    method public androidx.navigation.NavInflater getNavInflater();
-    method public androidx.navigation.NavigatorProvider getNavigatorProvider();
-    method public androidx.navigation.NavBackStackEntry? getPreviousBackStackEntry();
-    method public androidx.lifecycle.ViewModelStoreOwner getViewModelStoreOwner(@IdRes int navGraphId);
-    method public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getVisibleEntries();
-    method @MainThread public boolean handleDeepLink(android.content.Intent? intent);
-    method @MainThread public void navigate(@IdRes int resId);
-    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args);
-    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions);
-    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method @MainThread public void navigate(android.net.Uri deepLink);
-    method @MainThread public void navigate(android.net.Uri deepLink, androidx.navigation.NavOptions? navOptions);
-    method @MainThread public void navigate(android.net.Uri deepLink, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request);
-    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request, androidx.navigation.NavOptions? navOptions);
-    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method @MainThread public void navigate(androidx.navigation.NavDirections directions);
-    method @MainThread public void navigate(androidx.navigation.NavDirections directions, androidx.navigation.NavOptions? navOptions);
-    method @MainThread public void navigate(androidx.navigation.NavDirections directions, androidx.navigation.Navigator.Extras navigatorExtras);
-    method public final void navigate(String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> builder);
-    method public final void navigate(String route, optional androidx.navigation.NavOptions? navOptions, optional androidx.navigation.Navigator.Extras? navigatorExtras);
-    method public final void navigate(String route, optional androidx.navigation.NavOptions? navOptions);
-    method public final void navigate(String route);
-    method @MainThread public boolean navigateUp();
-    method @MainThread public boolean popBackStack();
-    method @MainThread public boolean popBackStack(@IdRes int destinationId, boolean inclusive);
-    method @MainThread public boolean popBackStack(@IdRes int destinationId, boolean inclusive, boolean saveState);
-    method @MainThread public final boolean popBackStack(String route, boolean inclusive, optional boolean saveState);
-    method @MainThread public final boolean popBackStack(String route, boolean inclusive);
-    method public void removeOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener listener);
-    method @CallSuper public void restoreState(android.os.Bundle? navState);
-    method @CallSuper public android.os.Bundle? saveState();
-    method @CallSuper @MainThread public void setGraph(androidx.navigation.NavGraph);
-    method @CallSuper @MainThread public void setGraph(@NavigationRes int graphResId);
-    method @CallSuper @MainThread public void setGraph(@NavigationRes int graphResId, android.os.Bundle? startDestinationArgs);
-    method @CallSuper @MainThread public void setGraph(androidx.navigation.NavGraph graph, android.os.Bundle? startDestinationArgs);
-    property public androidx.navigation.NavBackStackEntry? currentBackStackEntry;
-    property public final kotlinx.coroutines.flow.Flow<androidx.navigation.NavBackStackEntry> currentBackStackEntryFlow;
-    property public androidx.navigation.NavDestination? currentDestination;
-    property @MainThread public androidx.navigation.NavGraph graph;
-    property public androidx.navigation.NavInflater navInflater;
-    property public androidx.navigation.NavigatorProvider navigatorProvider;
-    property public androidx.navigation.NavBackStackEntry? previousBackStackEntry;
-    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> visibleEntries;
-    field public static final androidx.navigation.NavController.Companion Companion;
-    field public static final String KEY_DEEP_LINK_INTENT = "android-support-nav:controller:deepLinkIntent";
-  }
-
-  public static final class NavController.Companion {
-    method @androidx.navigation.NavDeepLinkSaveStateControl public void enableDeepLinkSaveState(boolean saveState);
-  }
-
-  public static fun interface NavController.OnDestinationChangedListener {
-    method public void onDestinationChanged(androidx.navigation.NavController controller, androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
-  }
-
-  public final class NavControllerKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavDeepLinkBuilder {
-    ctor public NavDeepLinkBuilder(android.content.Context context);
-    method public androidx.navigation.NavDeepLinkBuilder addDestination(@IdRes int destId, optional android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder addDestination(@IdRes int destId);
-    method public androidx.navigation.NavDeepLinkBuilder addDestination(String route, optional android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder addDestination(String route);
-    method public android.app.PendingIntent createPendingIntent();
-    method public androidx.core.app.TaskStackBuilder createTaskStackBuilder();
-    method public androidx.navigation.NavDeepLinkBuilder setArguments(android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder setComponentName(Class<? extends android.app.Activity> activityClass);
-    method public androidx.navigation.NavDeepLinkBuilder setComponentName(android.content.ComponentName componentName);
-    method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int destId, optional android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int destId);
-    method public androidx.navigation.NavDeepLinkBuilder setDestination(String destRoute, optional android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder setDestination(String destRoute);
-    method public androidx.navigation.NavDeepLinkBuilder setGraph(@NavigationRes int navGraphId);
-    method public androidx.navigation.NavDeepLinkBuilder setGraph(androidx.navigation.NavGraph navGraph);
-  }
-
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.WARNING) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface NavDeepLinkSaveStateControl {
-  }
-
-  public interface NavHost {
-    method public androidx.navigation.NavController getNavController();
-    property public abstract androidx.navigation.NavController navController;
-  }
-
-  public class NavHostController extends androidx.navigation.NavController {
-    ctor public NavHostController(android.content.Context context);
-    method public final void enableOnBackPressed(boolean enabled);
-    method public final void setLifecycleOwner(androidx.lifecycle.LifecycleOwner owner);
-    method public final void setOnBackPressedDispatcher(androidx.activity.OnBackPressedDispatcher dispatcher);
-    method public final void setViewModelStore(androidx.lifecycle.ViewModelStore viewModelStore);
-  }
-
-  public final class NavHostKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavInflater {
-    ctor public NavInflater(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider);
-    method public androidx.navigation.NavGraph inflate(@NavigationRes int graphResId);
-    field public static final androidx.navigation.NavInflater.Companion Companion;
-  }
-
-  public static final class NavInflater.Companion {
-  }
-
-  public final class Navigation {
-    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int resId, optional android.os.Bundle? args);
-    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int resId);
-    method public static android.view.View.OnClickListener createNavigateOnClickListener(androidx.navigation.NavDirections directions);
-    method public static androidx.navigation.NavController findNavController(android.app.Activity activity, @IdRes int viewId);
-    method public static androidx.navigation.NavController findNavController(android.view.View view);
-    method public static void setViewNavController(android.view.View view, androidx.navigation.NavController? controller);
-    field public static final androidx.navigation.Navigation INSTANCE;
-  }
-
-  public final class ViewKt {
-    method public static androidx.navigation.NavController findNavController(android.view.View);
-  }
-
-}
-
diff --git a/navigation/navigation-runtime/api/res-2.5.0-beta01.txt b/navigation/navigation-runtime/api/res-2.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/navigation/navigation-runtime/api/res-2.5.0-beta01.txt
+++ /dev/null
diff --git a/navigation/navigation-runtime/api/restricted_2.5.0-beta01.txt b/navigation/navigation-runtime/api/restricted_2.5.0-beta01.txt
deleted file mode 100644
index 7f117bb..0000000
--- a/navigation/navigation-runtime/api/restricted_2.5.0-beta01.txt
+++ /dev/null
@@ -1,224 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation {
-
-  public final class ActivityKt {
-    method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int viewId);
-  }
-
-  public final class ActivityNavArgsLazyKt {
-    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args>! navArgs(android.app.Activity);
-  }
-
-  @androidx.navigation.Navigator.Name("activity") public class ActivityNavigator extends androidx.navigation.Navigator<androidx.navigation.ActivityNavigator.Destination> {
-    ctor public ActivityNavigator(android.content.Context context);
-    method public static final void applyPopAnimationsToPendingTransition(android.app.Activity activity);
-    method public androidx.navigation.ActivityNavigator.Destination createDestination();
-    method public androidx.navigation.NavDestination? navigate(androidx.navigation.ActivityNavigator.Destination destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    field public static final androidx.navigation.ActivityNavigator.Companion Companion;
-  }
-
-  public static final class ActivityNavigator.Companion {
-    method public void applyPopAnimationsToPendingTransition(android.app.Activity activity);
-  }
-
-  @androidx.navigation.NavDestination.ClassType(Activity::class) public static class ActivityNavigator.Destination extends androidx.navigation.NavDestination {
-    ctor public ActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination> activityNavigator);
-    ctor public ActivityNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
-    method public final String? getAction();
-    method public final android.content.ComponentName? getComponent();
-    method public final android.net.Uri? getData();
-    method public final String? getDataPattern();
-    method public final android.content.Intent? getIntent();
-    method public final String? getTargetPackage();
-    method public final androidx.navigation.ActivityNavigator.Destination setAction(String? action);
-    method public final androidx.navigation.ActivityNavigator.Destination setComponentName(android.content.ComponentName? name);
-    method public final androidx.navigation.ActivityNavigator.Destination setData(android.net.Uri? data);
-    method public final androidx.navigation.ActivityNavigator.Destination setDataPattern(String? dataPattern);
-    method public final androidx.navigation.ActivityNavigator.Destination setIntent(android.content.Intent? intent);
-    method public final androidx.navigation.ActivityNavigator.Destination setTargetPackage(String? packageName);
-    property public final String? action;
-    property public final android.content.ComponentName? component;
-    property public final android.net.Uri? data;
-    property public final String? dataPattern;
-    property public final android.content.Intent? intent;
-    property public final String? targetPackage;
-  }
-
-  public static final class ActivityNavigator.Extras implements androidx.navigation.Navigator.Extras {
-    method public androidx.core.app.ActivityOptionsCompat? getActivityOptions();
-    method public int getFlags();
-    property public final androidx.core.app.ActivityOptionsCompat? activityOptions;
-    property public final int flags;
-  }
-
-  public static final class ActivityNavigator.Extras.Builder {
-    ctor public ActivityNavigator.Extras.Builder();
-    method public androidx.navigation.ActivityNavigator.Extras.Builder addFlags(int flags);
-    method public androidx.navigation.ActivityNavigator.Extras build();
-    method public androidx.navigation.ActivityNavigator.Extras.Builder setActivityOptions(androidx.core.app.ActivityOptionsCompat activityOptions);
-  }
-
-  @androidx.navigation.NavDestinationDsl public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
-    ctor @Deprecated public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
-    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, String route);
-    method public androidx.navigation.ActivityNavigator.Destination build();
-    method public String? getAction();
-    method public kotlin.reflect.KClass<? extends android.app.Activity>? getActivityClass();
-    method public android.net.Uri? getData();
-    method public String? getDataPattern();
-    method public String? getTargetPackage();
-    method public void setAction(String?);
-    method public void setActivityClass(kotlin.reflect.KClass<? extends android.app.Activity>?);
-    method public void setData(android.net.Uri?);
-    method public void setDataPattern(String?);
-    method public void setTargetPackage(String?);
-    property public final String? action;
-    property public final kotlin.reflect.KClass<? extends android.app.Activity>? activityClass;
-    property public final android.net.Uri? data;
-    property public final String? dataPattern;
-    property public final String? targetPackage;
-  }
-
-  public final class ActivityNavigatorDestinationBuilderKt {
-    method @Deprecated public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-    method public static inline void activity(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
-  }
-
-  public final class ActivityNavigatorExtrasKt {
-    method public static androidx.navigation.ActivityNavigator.Extras ActivityNavigatorExtras(optional androidx.core.app.ActivityOptionsCompat? activityOptions, optional int flags);
-  }
-
-  public class NavController {
-    ctor public NavController(android.content.Context context);
-    method public void addOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener listener);
-    method @MainThread public final boolean clearBackStack(String route);
-    method @MainThread public final boolean clearBackStack(@IdRes int destinationId);
-    method public androidx.navigation.NavDeepLinkBuilder createDeepLink();
-    method public androidx.navigation.NavBackStackEntry getBackStackEntry(@IdRes int destinationId);
-    method public final androidx.navigation.NavBackStackEntry getBackStackEntry(String route);
-    method public androidx.navigation.NavBackStackEntry? getCurrentBackStackEntry();
-    method public final kotlinx.coroutines.flow.Flow<androidx.navigation.NavBackStackEntry> getCurrentBackStackEntryFlow();
-    method public androidx.navigation.NavDestination? getCurrentDestination();
-    method @MainThread public androidx.navigation.NavGraph getGraph();
-    method public androidx.navigation.NavInflater getNavInflater();
-    method public androidx.navigation.NavigatorProvider getNavigatorProvider();
-    method public androidx.navigation.NavBackStackEntry? getPreviousBackStackEntry();
-    method public androidx.lifecycle.ViewModelStoreOwner getViewModelStoreOwner(@IdRes int navGraphId);
-    method public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getVisibleEntries();
-    method @MainThread public boolean handleDeepLink(android.content.Intent? intent);
-    method @MainThread public void navigate(@IdRes int resId);
-    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args);
-    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions);
-    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method @MainThread public void navigate(android.net.Uri deepLink);
-    method @MainThread public void navigate(android.net.Uri deepLink, androidx.navigation.NavOptions? navOptions);
-    method @MainThread public void navigate(android.net.Uri deepLink, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request);
-    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request, androidx.navigation.NavOptions? navOptions);
-    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
-    method @MainThread public void navigate(androidx.navigation.NavDirections directions);
-    method @MainThread public void navigate(androidx.navigation.NavDirections directions, androidx.navigation.NavOptions? navOptions);
-    method @MainThread public void navigate(androidx.navigation.NavDirections directions, androidx.navigation.Navigator.Extras navigatorExtras);
-    method public final void navigate(String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> builder);
-    method public final void navigate(String route, optional androidx.navigation.NavOptions? navOptions, optional androidx.navigation.Navigator.Extras? navigatorExtras);
-    method public final void navigate(String route, optional androidx.navigation.NavOptions? navOptions);
-    method public final void navigate(String route);
-    method @MainThread public boolean navigateUp();
-    method @MainThread public boolean popBackStack();
-    method @MainThread public boolean popBackStack(@IdRes int destinationId, boolean inclusive);
-    method @MainThread public boolean popBackStack(@IdRes int destinationId, boolean inclusive, boolean saveState);
-    method @MainThread public final boolean popBackStack(String route, boolean inclusive, optional boolean saveState);
-    method @MainThread public final boolean popBackStack(String route, boolean inclusive);
-    method public void removeOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener listener);
-    method @CallSuper public void restoreState(android.os.Bundle? navState);
-    method @CallSuper public android.os.Bundle? saveState();
-    method @CallSuper @MainThread public void setGraph(androidx.navigation.NavGraph);
-    method @CallSuper @MainThread public void setGraph(@NavigationRes int graphResId);
-    method @CallSuper @MainThread public void setGraph(@NavigationRes int graphResId, android.os.Bundle? startDestinationArgs);
-    method @CallSuper @MainThread public void setGraph(androidx.navigation.NavGraph graph, android.os.Bundle? startDestinationArgs);
-    property public androidx.navigation.NavBackStackEntry? currentBackStackEntry;
-    property public final kotlinx.coroutines.flow.Flow<androidx.navigation.NavBackStackEntry> currentBackStackEntryFlow;
-    property public androidx.navigation.NavDestination? currentDestination;
-    property @MainThread public androidx.navigation.NavGraph graph;
-    property public androidx.navigation.NavInflater navInflater;
-    property public androidx.navigation.NavigatorProvider navigatorProvider;
-    property public androidx.navigation.NavBackStackEntry? previousBackStackEntry;
-    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> visibleEntries;
-    field public static final androidx.navigation.NavController.Companion Companion;
-    field public static final String KEY_DEEP_LINK_INTENT = "android-support-nav:controller:deepLinkIntent";
-  }
-
-  public static final class NavController.Companion {
-  }
-
-  public static fun interface NavController.OnDestinationChangedListener {
-    method public void onDestinationChanged(androidx.navigation.NavController controller, androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
-  }
-
-  public final class NavControllerKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavDeepLinkBuilder {
-    ctor public NavDeepLinkBuilder(android.content.Context context);
-    method public androidx.navigation.NavDeepLinkBuilder addDestination(@IdRes int destId, optional android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder addDestination(@IdRes int destId);
-    method public androidx.navigation.NavDeepLinkBuilder addDestination(String route, optional android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder addDestination(String route);
-    method public android.app.PendingIntent createPendingIntent();
-    method public androidx.core.app.TaskStackBuilder createTaskStackBuilder();
-    method public androidx.navigation.NavDeepLinkBuilder setArguments(android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder setComponentName(Class<? extends android.app.Activity> activityClass);
-    method public androidx.navigation.NavDeepLinkBuilder setComponentName(android.content.ComponentName componentName);
-    method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int destId, optional android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int destId);
-    method public androidx.navigation.NavDeepLinkBuilder setDestination(String destRoute, optional android.os.Bundle? args);
-    method public androidx.navigation.NavDeepLinkBuilder setDestination(String destRoute);
-    method public androidx.navigation.NavDeepLinkBuilder setGraph(@NavigationRes int navGraphId);
-    method public androidx.navigation.NavDeepLinkBuilder setGraph(androidx.navigation.NavGraph navGraph);
-  }
-
-  public interface NavHost {
-    method public androidx.navigation.NavController getNavController();
-    property public abstract androidx.navigation.NavController navController;
-  }
-
-  public class NavHostController extends androidx.navigation.NavController {
-    ctor public NavHostController(android.content.Context context);
-    method public final void enableOnBackPressed(boolean enabled);
-    method public final void setLifecycleOwner(androidx.lifecycle.LifecycleOwner owner);
-    method public final void setOnBackPressedDispatcher(androidx.activity.OnBackPressedDispatcher dispatcher);
-    method public final void setViewModelStore(androidx.lifecycle.ViewModelStore viewModelStore);
-  }
-
-  public final class NavHostKt {
-    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
-  }
-
-  public final class NavInflater {
-    ctor public NavInflater(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider);
-    method public androidx.navigation.NavGraph inflate(@NavigationRes int graphResId);
-    field public static final androidx.navigation.NavInflater.Companion Companion;
-  }
-
-  public static final class NavInflater.Companion {
-  }
-
-  public final class Navigation {
-    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int resId, optional android.os.Bundle? args);
-    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int resId);
-    method public static android.view.View.OnClickListener createNavigateOnClickListener(androidx.navigation.NavDirections directions);
-    method public static androidx.navigation.NavController findNavController(android.app.Activity activity, @IdRes int viewId);
-    method public static androidx.navigation.NavController findNavController(android.view.View view);
-    method public static void setViewNavController(android.view.View view, androidx.navigation.NavController? controller);
-    field public static final androidx.navigation.Navigation INSTANCE;
-  }
-
-  public final class ViewKt {
-    method public static androidx.navigation.NavController findNavController(android.view.View);
-  }
-
-}
-
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt
index b53c19f..602e9f0 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt
@@ -184,6 +184,7 @@
         assertThat(ids).asList().containsExactly(R.id.nav_root, R.id.second_test)
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun generateExplicitStartDestinationWithArgs() {
         val deepLinkBuilder = NavDeepLinkBuilder(targetContext)
@@ -204,6 +205,7 @@
         assertThat(args).containsExactly("arg1", "arg2").inOrder()
     }
 
+    @Suppress("DEPRECATION")
     @Test
     fun generateExplicitNavRootWithArgs() {
         val deepLinkBuilder = NavDeepLinkBuilder(targetContext)
diff --git a/navigation/navigation-testing/api/2.5.0-beta01.txt b/navigation/navigation-testing/api/2.5.0-beta01.txt
deleted file mode 100644
index 89f60a4..0000000
--- a/navigation/navigation-testing/api/2.5.0-beta01.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.testing {
-
-  public final class TestNavHostController extends androidx.navigation.NavHostController {
-    ctor public TestNavHostController(android.content.Context context);
-    method public java.util.List<androidx.navigation.NavBackStackEntry> getBackStack();
-    method public void setCurrentDestination(@IdRes int destId, optional android.os.Bundle args);
-    method public void setCurrentDestination(@IdRes int destId);
-    method public void setCurrentDestination(String destRoute, optional android.os.Bundle args);
-    method public void setCurrentDestination(String destRoute);
-    property public final java.util.List<androidx.navigation.NavBackStackEntry> backStack;
-  }
-
-  public final class TestNavigatorState extends androidx.navigation.NavigatorState {
-    ctor public TestNavigatorState(optional android.content.Context? context, optional kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
-    ctor public TestNavigatorState(optional android.content.Context? context);
-    ctor public TestNavigatorState();
-    method public androidx.navigation.NavBackStackEntry createBackStackEntry(androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
-    method public androidx.navigation.NavBackStackEntry restoreBackStackEntry(androidx.navigation.NavBackStackEntry previouslySavedEntry);
-  }
-
-}
-
diff --git a/navigation/navigation-testing/api/public_plus_experimental_2.5.0-beta01.txt b/navigation/navigation-testing/api/public_plus_experimental_2.5.0-beta01.txt
deleted file mode 100644
index 89f60a4..0000000
--- a/navigation/navigation-testing/api/public_plus_experimental_2.5.0-beta01.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.testing {
-
-  public final class TestNavHostController extends androidx.navigation.NavHostController {
-    ctor public TestNavHostController(android.content.Context context);
-    method public java.util.List<androidx.navigation.NavBackStackEntry> getBackStack();
-    method public void setCurrentDestination(@IdRes int destId, optional android.os.Bundle args);
-    method public void setCurrentDestination(@IdRes int destId);
-    method public void setCurrentDestination(String destRoute, optional android.os.Bundle args);
-    method public void setCurrentDestination(String destRoute);
-    property public final java.util.List<androidx.navigation.NavBackStackEntry> backStack;
-  }
-
-  public final class TestNavigatorState extends androidx.navigation.NavigatorState {
-    ctor public TestNavigatorState(optional android.content.Context? context, optional kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
-    ctor public TestNavigatorState(optional android.content.Context? context);
-    ctor public TestNavigatorState();
-    method public androidx.navigation.NavBackStackEntry createBackStackEntry(androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
-    method public androidx.navigation.NavBackStackEntry restoreBackStackEntry(androidx.navigation.NavBackStackEntry previouslySavedEntry);
-  }
-
-}
-
diff --git a/navigation/navigation-testing/api/res-2.5.0-beta01.txt b/navigation/navigation-testing/api/res-2.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/navigation/navigation-testing/api/res-2.5.0-beta01.txt
+++ /dev/null
diff --git a/navigation/navigation-testing/api/restricted_2.5.0-beta01.txt b/navigation/navigation-testing/api/restricted_2.5.0-beta01.txt
deleted file mode 100644
index 89f60a4..0000000
--- a/navigation/navigation-testing/api/restricted_2.5.0-beta01.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.testing {
-
-  public final class TestNavHostController extends androidx.navigation.NavHostController {
-    ctor public TestNavHostController(android.content.Context context);
-    method public java.util.List<androidx.navigation.NavBackStackEntry> getBackStack();
-    method public void setCurrentDestination(@IdRes int destId, optional android.os.Bundle args);
-    method public void setCurrentDestination(@IdRes int destId);
-    method public void setCurrentDestination(String destRoute, optional android.os.Bundle args);
-    method public void setCurrentDestination(String destRoute);
-    property public final java.util.List<androidx.navigation.NavBackStackEntry> backStack;
-  }
-
-  public final class TestNavigatorState extends androidx.navigation.NavigatorState {
-    ctor public TestNavigatorState(optional android.content.Context? context, optional kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
-    ctor public TestNavigatorState(optional android.content.Context? context);
-    ctor public TestNavigatorState();
-    method public androidx.navigation.NavBackStackEntry createBackStackEntry(androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
-    method public androidx.navigation.NavBackStackEntry restoreBackStackEntry(androidx.navigation.NavBackStackEntry previouslySavedEntry);
-  }
-
-}
-
diff --git a/navigation/navigation-ui-ktx/api/2.5.0-beta01.txt b/navigation/navigation-ui-ktx/api/2.5.0-beta01.txt
deleted file mode 100644
index e6f50d0..0000000
--- a/navigation/navigation-ui-ktx/api/2.5.0-beta01.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 4.0
diff --git a/navigation/navigation-ui-ktx/api/public_plus_experimental_2.5.0-beta01.txt b/navigation/navigation-ui-ktx/api/public_plus_experimental_2.5.0-beta01.txt
deleted file mode 100644
index e6f50d0..0000000
--- a/navigation/navigation-ui-ktx/api/public_plus_experimental_2.5.0-beta01.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 4.0
diff --git a/navigation/navigation-ui-ktx/api/res-2.5.0-beta01.txt b/navigation/navigation-ui-ktx/api/res-2.5.0-beta01.txt
deleted file mode 100644
index e69de29..0000000
--- a/navigation/navigation-ui-ktx/api/res-2.5.0-beta01.txt
+++ /dev/null
diff --git a/navigation/navigation-ui-ktx/api/restricted_2.5.0-beta01.txt b/navigation/navigation-ui-ktx/api/restricted_2.5.0-beta01.txt
deleted file mode 100644
index e6f50d0..0000000
--- a/navigation/navigation-ui-ktx/api/restricted_2.5.0-beta01.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 4.0
diff --git a/navigation/navigation-ui/api/2.5.0-beta01.txt b/navigation/navigation-ui/api/2.5.0-beta01.txt
deleted file mode 100644
index 9551da2..0000000
--- a/navigation/navigation-ui/api/2.5.0-beta01.txt
+++ /dev/null
@@ -1,87 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.ui {
-
-  public final class ActivityKt {
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-  }
-
-  public final class AppBarConfiguration {
-    method @Deprecated public androidx.drawerlayout.widget.DrawerLayout? getDrawerLayout();
-    method public androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? getFallbackOnNavigateUpListener();
-    method public androidx.customview.widget.Openable? getOpenableLayout();
-    method public java.util.Set<java.lang.Integer> getTopLevelDestinations();
-    property @Deprecated public final androidx.drawerlayout.widget.DrawerLayout? drawerLayout;
-    property public final androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? fallbackOnNavigateUpListener;
-    property public final androidx.customview.widget.Openable? openableLayout;
-    property public final java.util.Set<java.lang.Integer> topLevelDestinations;
-  }
-
-  public static final class AppBarConfiguration.Builder {
-    ctor public AppBarConfiguration.Builder(androidx.navigation.NavGraph navGraph);
-    ctor public AppBarConfiguration.Builder(android.view.Menu topLevelMenu);
-    ctor public AppBarConfiguration.Builder(int... topLevelDestinationIds);
-    ctor public AppBarConfiguration.Builder(java.util.Set<java.lang.Integer> topLevelDestinationIds);
-    method public androidx.navigation.ui.AppBarConfiguration build();
-    method @Deprecated public androidx.navigation.ui.AppBarConfiguration.Builder setDrawerLayout(androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
-    method public androidx.navigation.ui.AppBarConfiguration.Builder setFallbackOnNavigateUpListener(androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? fallbackOnNavigateUpListener);
-    method public androidx.navigation.ui.AppBarConfiguration.Builder setOpenableLayout(androidx.customview.widget.Openable? openableLayout);
-  }
-
-  public static fun interface AppBarConfiguration.OnNavigateUpListener {
-    method public boolean onNavigateUp();
-  }
-
-  public final class AppBarConfigurationKt {
-    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(androidx.navigation.NavGraph navGraph, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
-    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(android.view.Menu topLevelMenu, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
-    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(java.util.Set<java.lang.Integer> topLevelDestinationIds, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
-  }
-
-  public final class BottomNavigationViewKt {
-    method public static void setupWithNavController(com.google.android.material.navigation.NavigationBarView, androidx.navigation.NavController navController);
-  }
-
-  public final class CollapsingToolbarLayoutKt {
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-  }
-
-  public final class MenuItemKt {
-    method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController navController);
-  }
-
-  public final class NavControllerKt {
-    method public static boolean navigateUp(androidx.navigation.NavController, androidx.customview.widget.Openable? drawerLayout);
-    method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration appBarConfiguration);
-  }
-
-  public final class NavigationUI {
-    method public static boolean navigateUp(androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
-    method public static boolean navigateUp(androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration);
-    method public static boolean onNavDestinationSelected(android.view.MenuItem item, androidx.navigation.NavController navController);
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController);
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController);
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController);
-    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView navigationView, androidx.navigation.NavController navController);
-    method public static void setupWithNavController(com.google.android.material.navigation.NavigationBarView navigationBarView, androidx.navigation.NavController navController);
-    field public static final androidx.navigation.ui.NavigationUI INSTANCE;
-  }
-
-  public final class NavigationViewKt {
-    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController navController);
-  }
-
-  public final class ToolbarKt {
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-  }
-
-}
-
diff --git a/navigation/navigation-ui/api/public_plus_experimental_2.5.0-beta01.txt b/navigation/navigation-ui/api/public_plus_experimental_2.5.0-beta01.txt
deleted file mode 100644
index 62b5ce4..0000000
--- a/navigation/navigation-ui/api/public_plus_experimental_2.5.0-beta01.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.ui {
-
-  public final class ActivityKt {
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-  }
-
-  public final class AppBarConfiguration {
-    method @Deprecated public androidx.drawerlayout.widget.DrawerLayout? getDrawerLayout();
-    method public androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? getFallbackOnNavigateUpListener();
-    method public androidx.customview.widget.Openable? getOpenableLayout();
-    method public java.util.Set<java.lang.Integer> getTopLevelDestinations();
-    property @Deprecated public final androidx.drawerlayout.widget.DrawerLayout? drawerLayout;
-    property public final androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? fallbackOnNavigateUpListener;
-    property public final androidx.customview.widget.Openable? openableLayout;
-    property public final java.util.Set<java.lang.Integer> topLevelDestinations;
-  }
-
-  public static final class AppBarConfiguration.Builder {
-    ctor public AppBarConfiguration.Builder(androidx.navigation.NavGraph navGraph);
-    ctor public AppBarConfiguration.Builder(android.view.Menu topLevelMenu);
-    ctor public AppBarConfiguration.Builder(int... topLevelDestinationIds);
-    ctor public AppBarConfiguration.Builder(java.util.Set<java.lang.Integer> topLevelDestinationIds);
-    method public androidx.navigation.ui.AppBarConfiguration build();
-    method @Deprecated public androidx.navigation.ui.AppBarConfiguration.Builder setDrawerLayout(androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
-    method public androidx.navigation.ui.AppBarConfiguration.Builder setFallbackOnNavigateUpListener(androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? fallbackOnNavigateUpListener);
-    method public androidx.navigation.ui.AppBarConfiguration.Builder setOpenableLayout(androidx.customview.widget.Openable? openableLayout);
-  }
-
-  public static fun interface AppBarConfiguration.OnNavigateUpListener {
-    method public boolean onNavigateUp();
-  }
-
-  public final class AppBarConfigurationKt {
-    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(androidx.navigation.NavGraph navGraph, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
-    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(android.view.Menu topLevelMenu, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
-    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(java.util.Set<java.lang.Integer> topLevelDestinationIds, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
-  }
-
-  public final class BottomNavigationViewKt {
-    method public static void setupWithNavController(com.google.android.material.navigation.NavigationBarView, androidx.navigation.NavController navController);
-  }
-
-  public final class CollapsingToolbarLayoutKt {
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-  }
-
-  public final class MenuItemKt {
-    method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController navController);
-  }
-
-  public final class NavControllerKt {
-    method public static boolean navigateUp(androidx.navigation.NavController, androidx.customview.widget.Openable? drawerLayout);
-    method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration appBarConfiguration);
-  }
-
-  public final class NavigationUI {
-    method public static boolean navigateUp(androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
-    method public static boolean navigateUp(androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration);
-    method public static boolean onNavDestinationSelected(android.view.MenuItem item, androidx.navigation.NavController navController);
-    method @androidx.navigation.ui.NavigationUiSaveStateControl public static boolean onNavDestinationSelected(android.view.MenuItem item, androidx.navigation.NavController navController, boolean saveState);
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController);
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController);
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController);
-    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView navigationView, androidx.navigation.NavController navController);
-    method @androidx.navigation.ui.NavigationUiSaveStateControl public static void setupWithNavController(com.google.android.material.navigation.NavigationView navigationView, androidx.navigation.NavController navController, boolean saveState);
-    method public static void setupWithNavController(com.google.android.material.navigation.NavigationBarView navigationBarView, androidx.navigation.NavController navController);
-    method @androidx.navigation.ui.NavigationUiSaveStateControl public static void setupWithNavController(com.google.android.material.navigation.NavigationBarView navigationBarView, androidx.navigation.NavController navController, boolean saveState);
-    field public static final androidx.navigation.ui.NavigationUI INSTANCE;
-  }
-
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.WARNING) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface NavigationUiSaveStateControl {
-  }
-
-  public final class NavigationViewKt {
-    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController navController);
-  }
-
-  public final class ToolbarKt {
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-  }
-
-}
-
diff --git a/navigation/navigation-ui/api/res-2.5.0-beta01.txt b/navigation/navigation-ui/api/res-2.5.0-beta01.txt
deleted file mode 100644
index e65fdbe..0000000
--- a/navigation/navigation-ui/api/res-2.5.0-beta01.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-anim nav_default_enter_anim
-anim nav_default_exit_anim
-anim nav_default_pop_enter_anim
-anim nav_default_pop_exit_anim
-animator nav_default_enter_anim
-animator nav_default_exit_anim
-animator nav_default_pop_enter_anim
-animator nav_default_pop_exit_anim
diff --git a/navigation/navigation-ui/api/restricted_2.5.0-beta01.txt b/navigation/navigation-ui/api/restricted_2.5.0-beta01.txt
deleted file mode 100644
index 9551da2..0000000
--- a/navigation/navigation-ui/api/restricted_2.5.0-beta01.txt
+++ /dev/null
@@ -1,87 +0,0 @@
-// Signature format: 4.0
-package androidx.navigation.ui {
-
-  public final class ActivityKt {
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-  }
-
-  public final class AppBarConfiguration {
-    method @Deprecated public androidx.drawerlayout.widget.DrawerLayout? getDrawerLayout();
-    method public androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? getFallbackOnNavigateUpListener();
-    method public androidx.customview.widget.Openable? getOpenableLayout();
-    method public java.util.Set<java.lang.Integer> getTopLevelDestinations();
-    property @Deprecated public final androidx.drawerlayout.widget.DrawerLayout? drawerLayout;
-    property public final androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? fallbackOnNavigateUpListener;
-    property public final androidx.customview.widget.Openable? openableLayout;
-    property public final java.util.Set<java.lang.Integer> topLevelDestinations;
-  }
-
-  public static final class AppBarConfiguration.Builder {
-    ctor public AppBarConfiguration.Builder(androidx.navigation.NavGraph navGraph);
-    ctor public AppBarConfiguration.Builder(android.view.Menu topLevelMenu);
-    ctor public AppBarConfiguration.Builder(int... topLevelDestinationIds);
-    ctor public AppBarConfiguration.Builder(java.util.Set<java.lang.Integer> topLevelDestinationIds);
-    method public androidx.navigation.ui.AppBarConfiguration build();
-    method @Deprecated public androidx.navigation.ui.AppBarConfiguration.Builder setDrawerLayout(androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
-    method public androidx.navigation.ui.AppBarConfiguration.Builder setFallbackOnNavigateUpListener(androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? fallbackOnNavigateUpListener);
-    method public androidx.navigation.ui.AppBarConfiguration.Builder setOpenableLayout(androidx.customview.widget.Openable? openableLayout);
-  }
-
-  public static fun interface AppBarConfiguration.OnNavigateUpListener {
-    method public boolean onNavigateUp();
-  }
-
-  public final class AppBarConfigurationKt {
-    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(androidx.navigation.NavGraph navGraph, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
-    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(android.view.Menu topLevelMenu, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
-    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(java.util.Set<java.lang.Integer> topLevelDestinationIds, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
-  }
-
-  public final class BottomNavigationViewKt {
-    method public static void setupWithNavController(com.google.android.material.navigation.NavigationBarView, androidx.navigation.NavController navController);
-  }
-
-  public final class CollapsingToolbarLayoutKt {
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-  }
-
-  public final class MenuItemKt {
-    method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController navController);
-  }
-
-  public final class NavControllerKt {
-    method public static boolean navigateUp(androidx.navigation.NavController, androidx.customview.widget.Openable? drawerLayout);
-    method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration appBarConfiguration);
-  }
-
-  public final class NavigationUI {
-    method public static boolean navigateUp(androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
-    method public static boolean navigateUp(androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration);
-    method public static boolean onNavDestinationSelected(android.view.MenuItem item, androidx.navigation.NavController navController);
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController);
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController);
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController);
-    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView navigationView, androidx.navigation.NavController navController);
-    method public static void setupWithNavController(com.google.android.material.navigation.NavigationBarView navigationBarView, androidx.navigation.NavController navController);
-    field public static final androidx.navigation.ui.NavigationUI INSTANCE;
-  }
-
-  public final class NavigationViewKt {
-    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController navController);
-  }
-
-  public final class ToolbarKt {
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
-    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
-  }
-
-}
-
diff --git a/preference/preference/src/main/java/androidx/preference/Preference.java b/preference/preference/src/main/java/androidx/preference/Preference.java
index 8872612..79d8a2d 100644
--- a/preference/preference/src/main/java/androidx/preference/Preference.java
+++ b/preference/preference/src/main/java/androidx/preference/Preference.java
@@ -25,6 +25,7 @@
 import android.content.SharedPreferences;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -2274,10 +2275,13 @@
             CharSequence summary = mPreference.getSummary();
             ClipData clip = ClipData.newPlainText(CLIPBOARD_ID, summary);
             clipboard.setPrimaryClip(clip);
-            Toast.makeText(mPreference.getContext(),
-                    mPreference.getContext().getString(R.string.preference_copied,
-                            summary),
-                    Toast.LENGTH_SHORT).show();
+            // T has a clipboard overlay that automatically shows copied text, so only show a Toast
+            // below T.
+            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
+                Toast.makeText(mPreference.getContext(),
+                        mPreference.getContext().getString(R.string.preference_copied, summary),
+                        Toast.LENGTH_SHORT).show();
+            }
             return true;
         }
     }
diff --git a/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/DeviceProfileWriter.java b/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/DeviceProfileWriter.java
index 694d2c1..0bcb376 100644
--- a/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/DeviceProfileWriter.java
+++ b/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/DeviceProfileWriter.java
@@ -307,6 +307,8 @@
                 return ProfileVersion.V010_P;
 
             case Build.VERSION_CODES.S:
+            case Build.VERSION_CODES.S_V2:
+            case Build.VERSION_CODES.TIRAMISU:
                 return ProfileVersion.V015_S;
 
             default:
@@ -339,6 +341,8 @@
 
             // The profiles for S require a typeIdCount. Therefore metadata is required.
             case Build.VERSION_CODES.S:
+            case Build.VERSION_CODES.S_V2:
+            case Build.VERSION_CODES.TIRAMISU:
                 return true;
 
             default:
diff --git a/recyclerview/recyclerview-selection/src/androidTest/java/androidx/recyclerview/selection/testing/TestData.java b/recyclerview/recyclerview-selection/src/androidTest/java/androidx/recyclerview/selection/testing/TestData.java
index 14e27aa..5fcd73a 100644
--- a/recyclerview/recyclerview-selection/src/androidTest/java/androidx/recyclerview/selection/testing/TestData.java
+++ b/recyclerview/recyclerview-selection/src/androidTest/java/androidx/recyclerview/selection/testing/TestData.java
@@ -31,8 +31,8 @@
 
     public static List<Long> createLongData(int num) {
         List<Long> items = new ArrayList<>(num);
-        for (int i = 0; i < num; ++i) {
-            items.add(new Long(i));
+        for (long i = 0; i < num; ++i) {
+            items.add(i);
         }
         return items;
     }
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/media/SampleMediaButtonReceiver.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/media/SampleMediaButtonReceiver.java
index 77e5126..3ad4b36 100644
--- a/samples/Support7Demos/src/main/java/com/example/android/supportv7/media/SampleMediaButtonReceiver.java
+++ b/samples/Support7Demos/src/main/java/com/example/android/supportv7/media/SampleMediaButtonReceiver.java
@@ -28,6 +28,7 @@
  * remote route volume in lock screen. It routes media key events back
  * to main app activity SampleMediaRouterActivity.
  */
+@SuppressWarnings("deprecation")
 public class SampleMediaButtonReceiver extends BroadcastReceiver {
     private static final String TAG = "SampleMediaButtonReceiver";
     private static SampleMediaRouterActivity mActivity;
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/media/SampleMediaRouteProvider.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/media/SampleMediaRouteProvider.java
index e695d7d..afe07ed9 100644
--- a/samples/Support7Demos/src/main/java/com/example/android/supportv7/media/SampleMediaRouteProvider.java
+++ b/samples/Support7Demos/src/main/java/com/example/android/supportv7/media/SampleMediaRouteProvider.java
@@ -51,6 +51,7 @@
  *
  * @see SampleMediaRouteProviderService
  */
+@SuppressWarnings("deprecation")
 class SampleMediaRouteProvider extends MediaRouteProvider {
     private static final String TAG = "SampleMrp";
 
diff --git a/samples/Support7Demos/src/main/java/com/example/android/supportv7/media/SampleMediaRouterActivity.java b/samples/Support7Demos/src/main/java/com/example/android/supportv7/media/SampleMediaRouterActivity.java
index 6f72b20..507d14e 100644
--- a/samples/Support7Demos/src/main/java/com/example/android/supportv7/media/SampleMediaRouterActivity.java
+++ b/samples/Support7Demos/src/main/java/com/example/android/supportv7/media/SampleMediaRouterActivity.java
@@ -78,6 +78,7 @@
  * targets.
  * </p>
  */
+@SuppressWarnings("deprecation")
 public class SampleMediaRouterActivity extends AppCompatActivity {
     private static final String TAG = "SampleMediaRouter";
     private static final String DISCOVERY_FRAGMENT_TAG = "DiscoveryFragment";
diff --git a/samples/SupportLeanbackDemos/src/main/java/com/example/android/leanback/DetailsActivity.java b/samples/SupportLeanbackDemos/src/main/java/com/example/android/leanback/DetailsActivity.java
index 6e2cbb4d..3f218ab 100644
--- a/samples/SupportLeanbackDemos/src/main/java/com/example/android/leanback/DetailsActivity.java
+++ b/samples/SupportLeanbackDemos/src/main/java/com/example/android/leanback/DetailsActivity.java
@@ -16,6 +16,7 @@
 import android.app.Activity;
 import android.os.Bundle;
 
+@SuppressWarnings("deprecation")
 public class DetailsActivity extends Activity
 {
     public static final String EXTRA_ITEM = "item";
diff --git a/samples/SupportLeanbackDemos/src/main/java/com/example/android/leanback/DetailsSupportActivity.java b/samples/SupportLeanbackDemos/src/main/java/com/example/android/leanback/DetailsSupportActivity.java
index f1a5ceb..8930028 100644
--- a/samples/SupportLeanbackDemos/src/main/java/com/example/android/leanback/DetailsSupportActivity.java
+++ b/samples/SupportLeanbackDemos/src/main/java/com/example/android/leanback/DetailsSupportActivity.java
@@ -20,6 +20,7 @@
 
 import androidx.fragment.app.FragmentActivity;
 
+@SuppressWarnings("deprecation")
 public class DetailsSupportActivity extends FragmentActivity
 {
     public static final String EXTRA_ITEM = "item";
diff --git a/savedstate/savedstate-ktx/api/1.2.0-beta01.txt b/savedstate/savedstate-ktx/api/1.2.0-beta01.txt
index b01f511..13e3138 100644
--- a/savedstate/savedstate-ktx/api/1.2.0-beta01.txt
+++ b/savedstate/savedstate-ktx/api/1.2.0-beta01.txt
@@ -2,7 +2,7 @@
 package androidx.savedstate {
 
   public final class ViewKt {
-    method @Deprecated public static androidx.savedstate.SavedStateRegistryOwner! findViewTreeSavedStateRegistryOwner(android.view.View);
+    method public static androidx.savedstate.SavedStateRegistryOwner? findViewTreeSavedStateRegistryOwner(android.view.View);
   }
 
 }
diff --git a/savedstate/savedstate-ktx/api/public_plus_experimental_1.2.0-beta01.txt b/savedstate/savedstate-ktx/api/public_plus_experimental_1.2.0-beta01.txt
index b01f511..13e3138 100644
--- a/savedstate/savedstate-ktx/api/public_plus_experimental_1.2.0-beta01.txt
+++ b/savedstate/savedstate-ktx/api/public_plus_experimental_1.2.0-beta01.txt
@@ -2,7 +2,7 @@
 package androidx.savedstate {
 
   public final class ViewKt {
-    method @Deprecated public static androidx.savedstate.SavedStateRegistryOwner! findViewTreeSavedStateRegistryOwner(android.view.View);
+    method public static androidx.savedstate.SavedStateRegistryOwner? findViewTreeSavedStateRegistryOwner(android.view.View);
   }
 
 }
diff --git a/savedstate/savedstate-ktx/api/restricted_1.2.0-beta01.txt b/savedstate/savedstate-ktx/api/restricted_1.2.0-beta01.txt
index b01f511..13e3138 100644
--- a/savedstate/savedstate-ktx/api/restricted_1.2.0-beta01.txt
+++ b/savedstate/savedstate-ktx/api/restricted_1.2.0-beta01.txt
@@ -2,7 +2,7 @@
 package androidx.savedstate {
 
   public final class ViewKt {
-    method @Deprecated public static androidx.savedstate.SavedStateRegistryOwner! findViewTreeSavedStateRegistryOwner(android.view.View);
+    method public static androidx.savedstate.SavedStateRegistryOwner? findViewTreeSavedStateRegistryOwner(android.view.View);
   }
 
 }
diff --git a/savedstate/savedstate/api/1.2.0-beta01.txt b/savedstate/savedstate/api/1.2.0-beta01.txt
index 6fe1a0d..45d2b1f9 100644
--- a/savedstate/savedstate/api/1.2.0-beta01.txt
+++ b/savedstate/savedstate/api/1.2.0-beta01.txt
@@ -2,8 +2,8 @@
 package androidx.savedstate {
 
   public final class SavedStateRegistry {
-    method @MainThread public android.os.Bundle? consumeRestoredStateForKey(String key);
-    method public androidx.savedstate.SavedStateRegistry.SavedStateProvider? getSavedStateProvider(String key);
+    method @MainThread public android.os.Bundle? consumeRestoredStateForKey(String);
+    method public androidx.savedstate.SavedStateRegistry.SavedStateProvider? getSavedStateProvider(String);
     method @MainThread public boolean isRestored();
     method @MainThread public void registerSavedStateProvider(String key, androidx.savedstate.SavedStateRegistry.SavedStateProvider provider);
     method @MainThread public void runOnNextRecreation(Class<? extends androidx.savedstate.SavedStateRegistry.AutoRecreated> clazz);
@@ -12,10 +12,10 @@
   }
 
   public static interface SavedStateRegistry.AutoRecreated {
-    method public void onRecreated(androidx.savedstate.SavedStateRegistryOwner owner);
+    method public void onRecreated(androidx.savedstate.SavedStateRegistryOwner);
   }
 
-  public static fun interface SavedStateRegistry.SavedStateProvider {
+  public static interface SavedStateRegistry.SavedStateProvider {
     method public android.os.Bundle saveState();
   }
 
@@ -35,12 +35,11 @@
 
   public interface SavedStateRegistryOwner extends androidx.lifecycle.LifecycleOwner {
     method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
-    property public abstract androidx.savedstate.SavedStateRegistry savedStateRegistry;
   }
 
   public final class ViewTreeSavedStateRegistryOwner {
     method public static androidx.savedstate.SavedStateRegistryOwner? get(android.view.View);
-    method public static void set(android.view.View, androidx.savedstate.SavedStateRegistryOwner? owner);
+    method public static void set(android.view.View, androidx.savedstate.SavedStateRegistryOwner?);
   }
 
 }
diff --git a/savedstate/savedstate/api/public_plus_experimental_1.2.0-beta01.txt b/savedstate/savedstate/api/public_plus_experimental_1.2.0-beta01.txt
index 6fe1a0d..45d2b1f9 100644
--- a/savedstate/savedstate/api/public_plus_experimental_1.2.0-beta01.txt
+++ b/savedstate/savedstate/api/public_plus_experimental_1.2.0-beta01.txt
@@ -2,8 +2,8 @@
 package androidx.savedstate {
 
   public final class SavedStateRegistry {
-    method @MainThread public android.os.Bundle? consumeRestoredStateForKey(String key);
-    method public androidx.savedstate.SavedStateRegistry.SavedStateProvider? getSavedStateProvider(String key);
+    method @MainThread public android.os.Bundle? consumeRestoredStateForKey(String);
+    method public androidx.savedstate.SavedStateRegistry.SavedStateProvider? getSavedStateProvider(String);
     method @MainThread public boolean isRestored();
     method @MainThread public void registerSavedStateProvider(String key, androidx.savedstate.SavedStateRegistry.SavedStateProvider provider);
     method @MainThread public void runOnNextRecreation(Class<? extends androidx.savedstate.SavedStateRegistry.AutoRecreated> clazz);
@@ -12,10 +12,10 @@
   }
 
   public static interface SavedStateRegistry.AutoRecreated {
-    method public void onRecreated(androidx.savedstate.SavedStateRegistryOwner owner);
+    method public void onRecreated(androidx.savedstate.SavedStateRegistryOwner);
   }
 
-  public static fun interface SavedStateRegistry.SavedStateProvider {
+  public static interface SavedStateRegistry.SavedStateProvider {
     method public android.os.Bundle saveState();
   }
 
@@ -35,12 +35,11 @@
 
   public interface SavedStateRegistryOwner extends androidx.lifecycle.LifecycleOwner {
     method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
-    property public abstract androidx.savedstate.SavedStateRegistry savedStateRegistry;
   }
 
   public final class ViewTreeSavedStateRegistryOwner {
     method public static androidx.savedstate.SavedStateRegistryOwner? get(android.view.View);
-    method public static void set(android.view.View, androidx.savedstate.SavedStateRegistryOwner? owner);
+    method public static void set(android.view.View, androidx.savedstate.SavedStateRegistryOwner?);
   }
 
 }
diff --git a/savedstate/savedstate/api/restricted_1.2.0-beta01.txt b/savedstate/savedstate/api/restricted_1.2.0-beta01.txt
index 6fe1a0d..45d2b1f9 100644
--- a/savedstate/savedstate/api/restricted_1.2.0-beta01.txt
+++ b/savedstate/savedstate/api/restricted_1.2.0-beta01.txt
@@ -2,8 +2,8 @@
 package androidx.savedstate {
 
   public final class SavedStateRegistry {
-    method @MainThread public android.os.Bundle? consumeRestoredStateForKey(String key);
-    method public androidx.savedstate.SavedStateRegistry.SavedStateProvider? getSavedStateProvider(String key);
+    method @MainThread public android.os.Bundle? consumeRestoredStateForKey(String);
+    method public androidx.savedstate.SavedStateRegistry.SavedStateProvider? getSavedStateProvider(String);
     method @MainThread public boolean isRestored();
     method @MainThread public void registerSavedStateProvider(String key, androidx.savedstate.SavedStateRegistry.SavedStateProvider provider);
     method @MainThread public void runOnNextRecreation(Class<? extends androidx.savedstate.SavedStateRegistry.AutoRecreated> clazz);
@@ -12,10 +12,10 @@
   }
 
   public static interface SavedStateRegistry.AutoRecreated {
-    method public void onRecreated(androidx.savedstate.SavedStateRegistryOwner owner);
+    method public void onRecreated(androidx.savedstate.SavedStateRegistryOwner);
   }
 
-  public static fun interface SavedStateRegistry.SavedStateProvider {
+  public static interface SavedStateRegistry.SavedStateProvider {
     method public android.os.Bundle saveState();
   }
 
@@ -35,12 +35,11 @@
 
   public interface SavedStateRegistryOwner extends androidx.lifecycle.LifecycleOwner {
     method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
-    property public abstract androidx.savedstate.SavedStateRegistry savedStateRegistry;
   }
 
   public final class ViewTreeSavedStateRegistryOwner {
     method public static androidx.savedstate.SavedStateRegistryOwner? get(android.view.View);
-    method public static void set(android.view.View, androidx.savedstate.SavedStateRegistryOwner? owner);
+    method public static void set(android.view.View, androidx.savedstate.SavedStateRegistryOwner?);
   }
 
 }
diff --git a/settings.gradle b/settings.gradle
index afc7025..c2e585f 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -78,8 +78,9 @@
             value("BUILD_NUMBER", buildNumber)
             link("ci.android.com build", "https://ci.android.com/builds/branches/aosp-androidx-main/grid?head=$buildNumber&tail=$buildNumber")
         }
-        publishAlways()
-        publishIfAuthenticated()
+        // Do not publish scan for androidx-platform-dev
+        // publishAlways()
+        // publishIfAuthenticated()
     }
 }
 
@@ -579,6 +580,7 @@
 includeProject(":health:health-connect-client", [BuildType.MAIN])
 includeProject(":health:health-services-client", [BuildType.MAIN])
 includeProject(":heifwriter:heifwriter", [BuildType.MAIN])
+includeProject(":graphics:graphics-core", [BuildType.MAIN])
 includeProject(":hilt:hilt-common", [BuildType.MAIN])
 includeProject(":hilt:hilt-compiler", [BuildType.MAIN])
 includeProject(":hilt:hilt-navigation", [BuildType.MAIN, BuildType.COMPOSE])
@@ -831,7 +833,7 @@
 includeProject(":window:extensions:extensions", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN])
 includeProject(":window:integration-tests:configuration-change-tests", [BuildType.MAIN])
 includeProject(":window:sidecar:sidecar", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN])
-includeProject(":window:window-java", [BuildType.MAIN])
+includeProject(":window:window-java", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN])
 includeProject(":window:window-rxjava2", [BuildType.MAIN])
 includeProject(":window:window-rxjava3", [BuildType.MAIN])
 includeProject(":window:window-samples", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN])
diff --git a/text/text/build.gradle b/text/text/build.gradle
index 1fd3a06..adbeebc 100644
--- a/text/text/build.gradle
+++ b/text/text/build.gradle
@@ -25,6 +25,7 @@
 
 dependencies {
     implementation(libs.kotlinStdlib)
+    implementation("androidx.core:core:1.7.0")
 
     api "androidx.annotation:annotation:1.2.0"
 
@@ -32,7 +33,6 @@
     testImplementation(libs.testRunner)
     testImplementation(libs.junit)
 
-    androidTestImplementation("androidx.core:core:1.5.0-rc02")
     androidTestImplementation(project(":compose:ui:ui-test-font"))
     androidTestImplementation(libs.testRules)
     androidTestImplementation(libs.testRunner)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/BoringLayoutFactoryTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/BoringLayoutFactoryTest.kt
index e4a4227..fba9e8f 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/BoringLayoutFactoryTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/BoringLayoutFactoryTest.kt
@@ -74,12 +74,42 @@
     }
 
     @Test
-    fun create_returnsGivenValues() {
+    fun create_returnsGivenValues_includePadding_false() {
         val text = "abc"
         val paint = TextPaint()
         val width = 100
         val metrics = BoringLayout.isBoring(text, paint)
-        val boringLayout = create(text, paint, width, metrics)
+        val boringLayout = create(
+            text = text,
+            paint = paint,
+            width = width,
+            metrics = metrics,
+            includePadding = false
+        )
+
+        assertThat(boringLayout.text).isEqualTo(text)
+        assertThat(boringLayout.paint).isEqualTo(paint)
+        // The width and height of the boringLayout is the same in metrics, indicating metrics is
+        // passed correctly.
+        assertThat(boringLayout.getLineWidth(0).toInt()).isEqualTo(metrics.width)
+        assertThat(boringLayout.getLineBottom(0) - boringLayout.getLineTop(0))
+            .isEqualTo(metrics.descent - metrics.ascent)
+        assertThat(boringLayout.width).isEqualTo(width)
+    }
+
+    @Test
+    fun create_returnsGivenValues_includePadding_true() {
+        val text = "abc"
+        val paint = TextPaint()
+        val width = 100
+        val metrics = BoringLayout.isBoring(text, paint)
+        val boringLayout = create(
+            text = text,
+            paint = paint,
+            width = width,
+            metrics = metrics,
+            includePadding = true
+        )
 
         assertThat(boringLayout.text).isEqualTo(text)
         assertThat(boringLayout.paint).isEqualTo(paint)
@@ -137,7 +167,7 @@
     }
 
     @Test
-    fun create_defaultIncludePad_isTrue() {
+    fun create_defaultIncludePad_isFalse() {
         val text: CharSequence = "abcdefghijk"
         val paint = TextPaint()
         val metrics = BoringLayout.isBoring(text, paint)
@@ -150,8 +180,8 @@
 
         val topPad = boringLayout.topPadding
         val bottomPad = boringLayout.bottomPadding
-        // Top and bottom padding are not 0 at the same time, indicating includePad is true.
-        assertThat(topPad * topPad + bottomPad * bottomPad).isGreaterThan(0)
+        // Top and bottom padding are 0 at the same time, indicating includePad is false
+        assertThat(topPad + bottomPad).isEqualTo(0)
     }
 
     @Test(expected = IllegalArgumentException::class)
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/BoringLayoutConstructor33.java b/text/text/src/main/java/androidx/compose/ui/text/android/BoringLayoutConstructor33.java
new file mode 100644
index 0000000..b1379e8
--- /dev/null
+++ b/text/text/src/main/java/androidx/compose/ui/text/android/BoringLayoutConstructor33.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2022 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.ui.text.android;
+
+import android.text.BoringLayout;
+import android.text.Layout;
+import android.text.TextPaint;
+import android.text.TextUtils;
+
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+
+/**
+ * Platform BoringLayout constructor has marked TextUtils.TruncateAt as NonNull even though it is
+ * nullable, and have to be nullable.
+ *
+ * This class has the same signature of the BoringLayout constructor with only difference of
+ * ellipsize is marked as Nullable.
+ *
+ * This was the only way to prevent compilation failure for nullability of TruncateAt ellipsize.
+ *
+ * See b/225695033
+ */
+@RequiresApi(33)
+class BoringLayoutConstructor33 {
+
+    private BoringLayoutConstructor33() {}
+
+    @NonNull
+    public static BoringLayout create(
+            @NonNull CharSequence text,
+            @NonNull TextPaint paint,
+            @IntRange(from = 0) int width,
+            @NonNull Layout.Alignment alignment,
+            float lineSpacingMultiplier,
+            float lineSpacingExtra,
+            @NonNull BoringLayout.Metrics metrics,
+            boolean includePadding,
+            @Nullable TextUtils.TruncateAt ellipsize,
+            @IntRange(from = 0) int ellipsizedWidth,
+            boolean useFallbackLineSpacing
+    ) {
+        return new BoringLayout(
+                text,
+                paint,
+                width,
+                alignment,
+                lineSpacingMultiplier,
+                lineSpacingExtra,
+                metrics,
+                includePadding,
+                ellipsize,
+                ellipsizedWidth,
+                useFallbackLineSpacing
+        );
+    }
+}
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/BoringLayoutFactory.kt b/text/text/src/main/java/androidx/compose/ui/text/android/BoringLayoutFactory.kt
index f4300cb..3a4efe8 100644
--- a/text/text/src/main/java/androidx/compose/ui/text/android/BoringLayoutFactory.kt
+++ b/text/text/src/main/java/androidx/compose/ui/text/android/BoringLayoutFactory.kt
@@ -15,12 +15,16 @@
  */
 package androidx.compose.ui.text.android
 
+import android.os.Build
 import android.text.BoringLayout
 import android.text.BoringLayout.Metrics
 import android.text.Layout.Alignment
+import android.text.StaticLayout
 import android.text.TextDirectionHeuristic
 import android.text.TextPaint
 import android.text.TextUtils.TruncateAt
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
 
 /**
  * Factory Class for BoringLayout
@@ -28,7 +32,7 @@
 @OptIn(InternalPlatformTextApi::class)
 internal object BoringLayoutFactory {
     /**
-     * Try to lay out text by BoringLayout with provided paint and text direction.
+     * Try to layout text by BoringLayout with provided paint and text direction.
      *
      * @param text the text to analyze.
      * @param paint TextPaint which carries text style parameters such as size, weight, font e.g.
@@ -38,13 +42,13 @@
      */
     fun measure(
         text: CharSequence,
-        paint: TextPaint?,
+        paint: TextPaint,
         textDir: TextDirectionHeuristic
     ): Metrics? {
-        return if (!textDir.isRtl(text, 0, text.length)) {
-            BoringLayout.isBoring(text, paint, null /* metrics */)
+        return if (Build.VERSION.SDK_INT >= 33) {
+            BoringLayoutFactory33.isBoring(text, paint, textDir)
         } else {
-            null
+            BoringLayoutFactoryDefault.isBoring(text, paint, textDir)
         }
     }
 
@@ -58,8 +62,15 @@
      * @param alignment To which edge the text is aligned.
      * @param includePadding Whether to add extra space beyond font ascent and descent (which is
      * needed to avoid clipping in some languages, such as Arabic and Kannada). Default is true.
+     * @param useFallbackLineSpacing Sets Android TextView#setFallbackLineSpacing. This value should
+     * be set to true in most cases and it is the default on platform; otherwise tall scripts such
+     * as Burmese or Tibetan result in clippings on top and bottom sometimes making the text
+     * not-readable.
      * @param ellipsize The ellipsize option specifying how the overflowed text is handled.
      * @param ellipsizedWidth The width where the exceeding text will be ellipsized, in pixel.
+     *
+     * @see BoringLayout.isFallbackLineSpacingEnabled
+     * @see StaticLayout.Builder.setUseLineSpacingFromFallbacks
      **/
     fun create(
         text: CharSequence,
@@ -67,14 +78,16 @@
         width: Int,
         metrics: Metrics,
         alignment: Alignment = Alignment.ALIGN_NORMAL,
-        includePadding: Boolean = true,
+        includePadding: Boolean = LayoutCompat.DEFAULT_INCLUDE_PADDING,
+        useFallbackLineSpacing: Boolean = LayoutCompat.DEFAULT_FALLBACK_LINE_SPACING,
         ellipsize: TruncateAt? = null,
-        ellipsizedWidth: Int = width
+        ellipsizedWidth: Int = width,
     ): BoringLayout {
         require(width >= 0)
         require(ellipsizedWidth >= 0)
-        return if (ellipsize == null) {
-            BoringLayout(
+
+        return if (Build.VERSION.SDK_INT >= 33) {
+            BoringLayoutFactory33.create(
                 text,
                 paint,
                 width,
@@ -82,10 +95,13 @@
                 LayoutCompat.DEFAULT_LINESPACING_MULTIPLIER,
                 LayoutCompat.DEFAULT_LINESPACING_EXTRA,
                 metrics,
-                includePadding
+                includePadding,
+                useFallbackLineSpacing,
+                ellipsize,
+                ellipsizedWidth
             )
         } else {
-            BoringLayout(
+            BoringLayoutFactoryDefault.create(
                 text,
                 paint,
                 width,
@@ -99,4 +115,106 @@
             )
         }
     }
+
+    /**
+     * Returns whether fallbackLineSpacing is enabled for the given layout.
+     */
+    fun isFallbackLineSpacingEnabled(layout: BoringLayout): Boolean {
+        return if (Build.VERSION.SDK_INT >= 33) {
+            BoringLayoutFactory33.isFallbackLineSpacingEnabled(layout)
+        } else {
+            return false
+        }
+    }
+}
+
+@RequiresApi(33)
+@OptIn(InternalPlatformTextApi::class)
+private object BoringLayoutFactory33 {
+
+    @JvmStatic
+    @DoNotInline
+    fun isBoring(text: CharSequence, paint: TextPaint, textDir: TextDirectionHeuristic): Metrics? {
+        return BoringLayout.isBoring(
+            text,
+            paint,
+            textDir,
+            LayoutCompat.DEFAULT_FALLBACK_LINE_SPACING,
+            null /* metrics */
+        )
+    }
+
+    @JvmStatic
+    @DoNotInline
+    fun create(
+        text: CharSequence,
+        paint: TextPaint,
+        width: Int,
+        alignment: Alignment,
+        lineSpacingMultiplier: Float,
+        lineSpacingExtra: Float,
+        metrics: Metrics,
+        includePadding: Boolean,
+        useFallbackLineSpacing: Boolean,
+        ellipsize: TruncateAt? = null,
+        ellipsizedWidth: Int = width
+    ): BoringLayout {
+        return BoringLayoutConstructor33.create(
+            text,
+            paint,
+            width,
+            alignment,
+            lineSpacingMultiplier,
+            lineSpacingExtra,
+            metrics,
+            includePadding,
+            ellipsize,
+            ellipsizedWidth,
+            useFallbackLineSpacing
+        )
+    }
+
+    fun isFallbackLineSpacingEnabled(layout: BoringLayout): Boolean {
+        return layout.isFallbackLineSpacingEnabled
+    }
+}
+
+private object BoringLayoutFactoryDefault {
+    @JvmStatic
+    @DoNotInline
+    fun isBoring(text: CharSequence, paint: TextPaint, textDir: TextDirectionHeuristic): Metrics? {
+        return if (!textDir.isRtl(text, 0, text.length)) {
+            return BoringLayout.isBoring(text, paint, null /* metrics */)
+        } else {
+            null
+        }
+    }
+
+    @JvmStatic
+    @DoNotInline
+    fun create(
+        text: CharSequence,
+        paint: TextPaint,
+        width: Int,
+        alignment: Alignment,
+        lineSpacingMultiplier: Float,
+        lineSpacingExtra: Float,
+        metrics: Metrics,
+        includePadding: Boolean,
+        ellipsize: TruncateAt? = null,
+        ellipsizedWidth: Int = width
+    ): BoringLayout {
+        return BoringLayout(
+            text,
+            paint,
+            width,
+            alignment,
+            lineSpacingMultiplier,
+            lineSpacingExtra,
+            metrics,
+            includePadding,
+            ellipsize,
+            ellipsizedWidth
+        )
+    }
 }
\ No newline at end of file
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/StaticLayoutFactory.kt b/text/text/src/main/java/androidx/compose/ui/text/android/StaticLayoutFactory.kt
index ef17dfb..2c57881 100644
--- a/text/text/src/main/java/androidx/compose/ui/text/android/StaticLayoutFactory.kt
+++ b/text/text/src/main/java/androidx/compose/ui/text/android/StaticLayoutFactory.kt
@@ -41,7 +41,7 @@
     private val delegate: StaticLayoutFactoryImpl = if (Build.VERSION.SDK_INT >= 23) {
         StaticLayoutFactory23()
     } else {
-        StaticLayoutFactoryPre21()
+        StaticLayoutFactoryDefault()
     }
 
     /**
@@ -98,6 +98,20 @@
             )
         )
     }
+
+    /**
+     * Returns whether fallbackLineSpacing is enabled for the given layout.
+     *
+     * @param layout StaticLayout instance
+     * @param useFallbackLineSpacing fallbackLineSpacing canfiguration passed while creating the
+     * StaticLayout.
+     */
+    fun isFallbackLineSpacingEnabled(
+        layout: StaticLayout,
+        useFallbackLineSpacing: Boolean
+    ): Boolean {
+        return delegate.isFallbackLineSpacingEnabled(layout, useFallbackLineSpacing)
+    }
 }
 
 @OptIn(InternalPlatformTextApi::class)
@@ -136,6 +150,8 @@
 
     @DoNotInline // API level specific, do not inline to prevent ART class verification breakages
     fun create(params: StaticLayoutParams): StaticLayout
+
+    fun isFallbackLineSpacingEnabled(layout: StaticLayout, useFallbackLineSpacing: Boolean): Boolean
 }
 
 @RequiresApi(23)
@@ -166,10 +182,24 @@
                 }
             }.build()
     }
+
+    override fun isFallbackLineSpacingEnabled(
+        layout: StaticLayout,
+        useFallbackLineSpacing: Boolean
+    ): Boolean {
+        return if (Build.VERSION.SDK_INT >= 33) {
+            StaticLayoutFactory33.isFallbackLineSpacingEnabled(layout)
+        } else if (Build.VERSION.SDK_INT >= 28) {
+            useFallbackLineSpacing
+        } else {
+            false
+        }
+    }
 }
 
 @RequiresApi(26)
 private object StaticLayoutFactory26 {
+    @JvmStatic
     @DoNotInline
     fun setJustificationMode(builder: Builder, justificationMode: Int) {
         builder.setJustificationMode(justificationMode)
@@ -178,13 +208,23 @@
 
 @RequiresApi(28)
 private object StaticLayoutFactory28 {
+    @JvmStatic
     @DoNotInline
     fun setUseLineSpacingFromFallbacks(builder: Builder, useFallbackLineSpacing: Boolean) {
         builder.setUseLineSpacingFromFallbacks(useFallbackLineSpacing)
     }
 }
 
-private class StaticLayoutFactoryPre21 : StaticLayoutFactoryImpl {
+@RequiresApi(33)
+private object StaticLayoutFactory33 {
+    @JvmStatic
+    @DoNotInline
+    fun isFallbackLineSpacingEnabled(layout: StaticLayout): Boolean {
+        return layout.isFallbackLineSpacingEnabled
+    }
+}
+
+private class StaticLayoutFactoryDefault : StaticLayoutFactoryImpl {
 
     companion object {
         private var isInitialized = false
@@ -274,4 +314,11 @@
             params.ellipsizedWidth
         )
     }
+
+    override fun isFallbackLineSpacingEnabled(
+        layout: StaticLayout,
+        useFallbackLineSpacing: Boolean
+    ): Boolean {
+        return false
+    }
 }
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/TextLayout.kt b/text/text/src/main/java/androidx/compose/ui/text/android/TextLayout.kt
index 7a645c1..a0c1bdb 100644
--- a/text/text/src/main/java/androidx/compose/ui/text/android/TextLayout.kt
+++ b/text/text/src/main/java/androidx/compose/ui/text/android/TextLayout.kt
@@ -17,9 +17,10 @@
 
 import android.graphics.Canvas
 import android.graphics.Path
-import android.os.Build
+import android.text.BoringLayout
 import android.text.Layout
 import android.text.Spanned
+import android.text.StaticLayout
 import android.text.TextDirectionHeuristic
 import android.text.TextDirectionHeuristics
 import android.text.TextPaint
@@ -70,7 +71,11 @@
  * @param lineSpacingMultiplier the multiplier to be applied to each line of the text.
  * @param lineSpacingExtra the extra height to be added to each line of the text.
  * @param includePadding defines whether the extra space to be applied beyond font ascent and
- * descent,
+ * descent
+ * @param fallbackLineSpacing Sets Android TextView#setFallbackLineSpacing. This value should
+ * be set to true in most cases and it is the default on platform; otherwise tall scripts such
+ * as Burmese or Tibetan result in clippings on top and bottom sometimes making the text
+ * not-readable.
  * @param maxLines the maximum number of lines to be laid out.
  * @param breakStrategy the strategy to be used for line breaking
  * @param hyphenationFrequency set the frequency to control the amount of automatic hyphenation
@@ -83,7 +88,9 @@
  * element in the array is applied to the corresponding line. For lines past the last element in
  * array, the last element repeats.
  * @param layoutIntrinsics previously calculated [LayoutIntrinsics] for this text
+ *
  * @see StaticLayoutFactory
+ * @see BoringLayoutFactory
  *
  * @suppress
  */
@@ -176,6 +183,7 @@
                 metrics = boringMetrics,
                 alignment = frameworkAlignment,
                 includePadding = includePadding,
+                useFallbackLineSpacing = fallbackLineSpacing,
                 ellipsize = ellipsize,
                 ellipsizedWidth = widthInt
             )
@@ -458,7 +466,14 @@
     }
 
     internal fun isFallbackLinespacingApplied(): Boolean {
-        return fallbackLineSpacing && !isBoringLayout && Build.VERSION.SDK_INT >= 28
+        return if (isBoringLayout) {
+            BoringLayoutFactory.isFallbackLineSpacingEnabled(layout as BoringLayout)
+        } else {
+            StaticLayoutFactory.isFallbackLineSpacingEnabled(
+                layout as StaticLayout,
+                fallbackLineSpacing
+            )
+        }
     }
 }
 
diff --git a/wear/watchface/watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionTest.kt b/wear/watchface/watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionTest.kt
index 0fc43fc..5d2cdbb 100644
--- a/wear/watchface/watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionTest.kt
+++ b/wear/watchface/watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionTest.kt
@@ -1114,6 +1114,7 @@
         }
     }
 
+    @Suppress("DEPRECATION")
     @Test
     public fun launchComplicationDataSourceChooser() {
         ComplicationDataSourceChooserContract.useTestComplicationHelperActivity = true
diff --git a/wear/watchface/watchface-editor/src/main/java/androidx/wear/watchface/editor/EditorSession.kt b/wear/watchface/watchface-editor/src/main/java/androidx/wear/watchface/editor/EditorSession.kt
index 70046c3..a6b65d1 100644
--- a/wear/watchface/watchface-editor/src/main/java/androidx/wear/watchface/editor/EditorSession.kt
+++ b/wear/watchface/watchface-editor/src/main/java/androidx/wear/watchface/editor/EditorSession.kt
@@ -276,6 +276,7 @@
         }
 
         // Used by tests.
+        @Suppress("DEPRECATION")
         @Throws(TimeoutCancellationException::class)
         internal suspend fun createOnWatchEditorSessionImpl(
             activity: ComponentActivity,
@@ -1072,6 +1073,7 @@
         return intent
     }
 
+    @Suppress("DEPRECATION")
     override fun parseResult(resultCode: Int, intent: Intent?) = intent?.let {
         val extras = intent.extras?.let { extras ->
             Bundle(extras).apply { remove(EXTRA_PROVIDER_INFO) }
diff --git a/wear/watchface/watchface-editor/src/main/java/androidx/wear/watchface/editor/WatchFaceEditorContract.kt b/wear/watchface/watchface-editor/src/main/java/androidx/wear/watchface/editor/WatchFaceEditorContract.kt
index a266048..4ece658 100644
--- a/wear/watchface/watchface-editor/src/main/java/androidx/wear/watchface/editor/WatchFaceEditorContract.kt
+++ b/wear/watchface/watchface-editor/src/main/java/androidx/wear/watchface/editor/WatchFaceEditorContract.kt
@@ -138,6 +138,7 @@
          * if there is one or `null` otherwise. Intended for use by the watch face editor activity.
          * @throws [TimeoutCancellationException] in case of en error.
          */
+        @Suppress("DEPRECATION")
         @SuppressLint("NewApi")
         @JvmStatic
         @Throws(TimeoutCancellationException::class)
diff --git a/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/ComplicationHelperActivityTest.kt b/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/ComplicationHelperActivityTest.kt
index 2294c89..f3218ce 100644
--- a/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/ComplicationHelperActivityTest.kt
+++ b/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/ComplicationHelperActivityTest.kt
@@ -314,6 +314,7 @@
 }
 
 /** The watch face component name encoded in the intent. */
+@Suppress("DEPRECATION")
 private val Intent.watchFaceComponentName
     get() = getParcelableExtra<ComponentName>(
         ComplicationDataSourceChooserIntent.EXTRA_WATCH_FACE_COMPONENT_NAME
diff --git a/wear/watchface/watchface/src/main/java/androidx/wear/watchface/ComplicationHelperActivity.java b/wear/watchface/watchface/src/main/java/androidx/wear/watchface/ComplicationHelperActivity.java
index b5853f9..0cac46c 100644
--- a/wear/watchface/watchface/src/main/java/androidx/wear/watchface/ComplicationHelperActivity.java
+++ b/wear/watchface/watchface/src/main/java/androidx/wear/watchface/ComplicationHelperActivity.java
@@ -183,6 +183,7 @@
         }
 
         @Override
+        @SuppressWarnings("deprecation")
         public void launchComplicationDeniedActivity() {
             Intent complicationDeniedIntent =
                     mActivity.getIntent().getParcelableExtra(
@@ -222,6 +223,7 @@
         start(true);
     }
 
+    @SuppressWarnings("deprecation")
     void start(boolean shouldShowRequestPermissionRationale) {
         if (shouldShowRequestPermissionRationale
                 && mDelegate.shouldShowRequestPermissionRationale()) {
diff --git a/wear/wear-input/src/main/java/androidx/wear/input/RemoteInputIntentHelper.kt b/wear/wear-input/src/main/java/androidx/wear/input/RemoteInputIntentHelper.kt
index 4d8d6fc..87ded0e 100644
--- a/wear/wear-input/src/main/java/androidx/wear/input/RemoteInputIntentHelper.kt
+++ b/wear/wear-input/src/main/java/androidx/wear/input/RemoteInputIntentHelper.kt
@@ -100,6 +100,7 @@
          * @return The array of [RemoteInput] previously added with [putRemoteInputsExtra] or null
          * which means no user input required.
          */
+        @Suppress("DEPRECATION")
         @JvmStatic
         @Nullable
         public fun getRemoteInputsExtra(intent: Intent): List<RemoteInput>? =
diff --git a/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/RemoteActivityHelper.kt b/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/RemoteActivityHelper.kt
index 47c4577..3c9f8ba 100644
--- a/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/RemoteActivityHelper.kt
+++ b/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/RemoteActivityHelper.kt
@@ -97,6 +97,7 @@
          * @param intent The intent holding configuration.
          * @return The remote intent, or null if none was set.
          */
+        @Suppress("DEPRECATION")
         @JvmStatic
         public fun getTargetIntent(intent: Intent): Intent? =
             intent.getParcelableExtra(EXTRA_INTENT)
@@ -117,6 +118,7 @@
          * @param intent The intent holding configuration.
          * @return The result receiver, or null if none was set.
          */
+        @Suppress("DEPRECATION")
         @JvmStatic
         internal fun getRemoteIntentResultReceiver(intent: Intent): ResultReceiver? =
             intent.getParcelableExtra(EXTRA_RESULT_RECEIVER)
diff --git a/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/WatchFaceConfigIntentHelper.kt b/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/WatchFaceConfigIntentHelper.kt
index 99aa404..54eefab 100644
--- a/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/WatchFaceConfigIntentHelper.kt
+++ b/wear/wear-remote-interactions/src/main/java/androidx/wear/remote/interactions/WatchFaceConfigIntentHelper.kt
@@ -85,6 +85,7 @@
          * @return the value of an item previously added with [putWatchFaceComponentExtra], or
          * null if no value was found.
          */
+        @Suppress("DEPRECATION")
         @JvmStatic
         @Nullable
         public fun getWatchFaceComponentExtra(watchFaceIntent: Intent): ComponentName? =
diff --git a/window/extensions/extensions/api/public_plus_experimental_current.txt b/window/extensions/extensions/api/public_plus_experimental_current.txt
index 6a28e00..ad88a4a 100644
--- a/window/extensions/extensions/api/public_plus_experimental_current.txt
+++ b/window/extensions/extensions/api/public_plus_experimental_current.txt
@@ -7,6 +7,7 @@
   public interface WindowExtensions {
     method @androidx.window.extensions.ExperimentalWindowExtensionsApi public androidx.window.extensions.embedding.ActivityEmbeddingComponent? getActivityEmbeddingComponent();
     method public default int getVendorApiLevel();
+    method @androidx.window.extensions.ExperimentalWindowExtensionsApi public androidx.window.extensions.area.WindowAreaComponent? getWindowAreaComponent();
     method public androidx.window.extensions.layout.WindowLayoutComponent? getWindowLayoutComponent();
   }
 
@@ -16,6 +17,22 @@
 
 }
 
+package androidx.window.extensions.area {
+
+  @androidx.window.extensions.ExperimentalWindowExtensionsApi public interface WindowAreaComponent {
+    method public void addRearDisplayStatusListener(java.util.function.Consumer<java.lang.Integer!>);
+    method public void endRearDisplaySession();
+    method public void removeRearDisplayStatusListener(java.util.function.Consumer<java.lang.Integer!>);
+    method public void startRearDisplaySession(android.app.Activity, java.util.function.Consumer<java.lang.Integer!>);
+    field public static final int SESSION_STATE_ACTIVE = 1; // 0x1
+    field public static final int SESSION_STATE_INACTIVE = 0; // 0x0
+    field public static final int STATUS_AVAILABLE = 2; // 0x2
+    field public static final int STATUS_UNAVAILABLE = 1; // 0x1
+    field public static final int STATUS_UNSUPPORTED = 0; // 0x0
+  }
+
+}
+
 package androidx.window.extensions.embedding {
 
   @androidx.window.extensions.ExperimentalWindowExtensionsApi public interface ActivityEmbeddingComponent {
diff --git a/window/extensions/extensions/src/main/java/androidx/window/extensions/WindowExtensions.java b/window/extensions/extensions/src/main/java/androidx/window/extensions/WindowExtensions.java
index 6ac25bd..ca3a882 100644
--- a/window/extensions/extensions/src/main/java/androidx/window/extensions/WindowExtensions.java
+++ b/window/extensions/extensions/src/main/java/androidx/window/extensions/WindowExtensions.java
@@ -17,6 +17,7 @@
 package androidx.window.extensions;
 
 import androidx.annotation.Nullable;
+import androidx.window.extensions.area.WindowAreaComponent;
 import androidx.window.extensions.embedding.ActivityEmbeddingComponent;
 import androidx.window.extensions.layout.WindowLayoutComponent;
 
@@ -60,4 +61,14 @@
     @Nullable
     @ExperimentalWindowExtensionsApi
     ActivityEmbeddingComponent getActivityEmbeddingComponent();
+
+    /**
+     * Returns the OEM implementation of {@link WindowAreaComponent} if it is supported on
+     * the device, {@code null} otherwise. The implementation must match the API level reported in
+     * {@link WindowExtensions}.
+     * @return the OEM implementation of {@link WindowAreaComponent}
+     */
+    @Nullable
+    @ExperimentalWindowExtensionsApi
+    WindowAreaComponent getWindowAreaComponent();
 }
diff --git a/window/extensions/extensions/src/main/java/androidx/window/extensions/area/WindowAreaComponent.java b/window/extensions/extensions/src/main/java/androidx/window/extensions/area/WindowAreaComponent.java
new file mode 100644
index 0000000..a565eda
--- /dev/null
+++ b/window/extensions/extensions/src/main/java/androidx/window/extensions/area/WindowAreaComponent.java
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ * 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.window.extensions.area;
+
+import android.app.Activity;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.window.extensions.ExperimentalWindowExtensionsApi;
+import androidx.window.extensions.WindowExtensions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.function.Consumer;
+
+/**
+ * The interface definition that will be used by the WindowManager library to get custom
+ * OEM-provided behavior around moving windows between displays or display areas on a device.
+ *
+ * Currently the only behavior supported is RearDisplay Mode, where the window
+ * is moved to the display that faces the same direction as the rear camera.
+ *
+ * <p>This interface should be implemented by OEM and deployed to the target devices.
+ * @see WindowExtensions#getWindowLayoutComponent()
+ */
+@ExperimentalWindowExtensionsApi
+public interface WindowAreaComponent {
+
+    /**
+     * WindowArea status constant to signify that the feature is
+     * unsupported on this device. Could be due to the device not supporting that
+     * specific feature.
+     */
+    int STATUS_UNSUPPORTED = 0;
+
+    /**
+     * WindowArea status constant to signify that the feature is
+     * currently unavailable but is supported on this device. This value could signify
+     * that the current device state does not support the specific feature or another
+     * process is currently enabled in that feature.
+     */
+    int STATUS_UNAVAILABLE = 1;
+
+    /**
+     * WindowArea status constant to signify that the feature is
+     * available to be entered or enabled.
+     */
+    int STATUS_AVAILABLE = 2;
+
+    /** @hide */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            STATUS_UNSUPPORTED,
+            STATUS_UNAVAILABLE,
+            STATUS_AVAILABLE
+    })
+    @interface WindowAreaStatus {}
+
+    /**
+     * Session state constant to represent there being no active session
+     * currently in progress. Used by the library to call the correct callbacks if
+     * a session is ended.
+     */
+    int SESSION_STATE_INACTIVE = 0;
+
+    /**
+     * Session state constant to represent that there is an
+     * active session currently in progress. Used by the library to
+     * know when to return the session object to the developer when the
+     * session is created and active.
+     */
+    int SESSION_STATE_ACTIVE = 1;
+
+    /** @hide */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            SESSION_STATE_ACTIVE,
+            SESSION_STATE_INACTIVE
+    })
+    @interface WindowAreaSessionState {}
+
+    /**
+     * Adds a listener interested in receiving updates on the RearDisplayStatus
+     * of the device. Because this is being called from the OEM provided
+     * extensions, the library will post the result of the listener on the executor
+     * provided by the developer.
+     *
+     * The listener provided will receive values that
+     * correspond to the [WindowAreaStatus] value that aligns with the current status
+     * of the rear display.
+     * @param consumer interested in receiving updates to WindowAreaStatus.
+     */
+    void addRearDisplayStatusListener(@NonNull Consumer<Integer> consumer);
+
+    /**
+     * Removes a listener no longer interested in receiving updates.
+     * @param consumer no longer interested in receiving updates to WindowAreaStatus
+     */
+    void removeRearDisplayStatusListener(@NonNull Consumer<Integer> consumer);
+
+
+    /**
+     * Creates and starts a rear display session and sends state updates to the
+     * consumer provided. This consumer will receive a constant represented by
+     * [WindowAreaSessionState] to represent the state of the current rear display
+     * session. We will translate to a more friendly interface in the library.
+     *
+     * Because this is being called from the OEM provided extensions, the library
+     * will post the result of the listener on the executor provided by the developer.
+     *
+     * @param activity to allow that the OEM implementation will use as a base
+     * context and to identify the source display area of the request.
+     * The reference to the activity instance must not be stored in the OEM
+     * implementation to prevent memory leaks.
+     * @param consumer to provide updates to the client on the status of the session
+     * @throws UnsupportedOperationException if this method is called when RearDisplay
+     * mode is not available. This could be to an incompatible device state or when
+     * another process is currently in this mode.
+     */
+    @SuppressWarnings("ExecutorRegistration") // Jetpack will post it on the app-provided executor.
+    void startRearDisplaySession(@NonNull Activity activity,
+            @NonNull Consumer<Integer> consumer);
+
+    /**
+     * Ends a RearDisplaySession and sends [STATE_INACTIVE] to the consumer
+     * provided in the {@code startRearDisplaySession} method. This method is only
+     * called through the {@code RearDisplaySession} provided to the developer.
+     */
+    void endRearDisplaySession();
+}
diff --git a/window/window-java/api/public_plus_experimental_current.txt b/window/window-java/api/public_plus_experimental_current.txt
index 709904b..a56988b 100644
--- a/window/window-java/api/public_plus_experimental_current.txt
+++ b/window/window-java/api/public_plus_experimental_current.txt
@@ -1,4 +1,15 @@
 // Signature format: 4.0
+package androidx.window.java.area {
+
+  @androidx.window.core.ExperimentalWindowApi public final class WindowAreaControllerJavaAdapter implements androidx.window.area.WindowAreaController {
+    ctor public WindowAreaControllerJavaAdapter(androidx.window.area.WindowAreaController controller);
+    method public void addRearDisplayStatusListener(java.util.concurrent.Executor executor, androidx.core.util.Consumer<androidx.window.area.WindowAreaStatus> consumer);
+    method public void removeRearDisplayStatusListener(androidx.core.util.Consumer<androidx.window.area.WindowAreaStatus> consumer);
+    method public void startRearDisplayModeSession(android.app.Activity activity, java.util.concurrent.Executor executor, androidx.window.area.WindowAreaSessionCallback windowAreaSessionCallback);
+  }
+
+}
+
 package androidx.window.java.layout {
 
   public final class WindowInfoTrackerCallbackAdapter implements androidx.window.layout.WindowInfoTracker {
diff --git a/window/window-java/src/main/java/androidx/window/java/area/WindowAreaControllerJavaAdapter.kt b/window/window-java/src/main/java/androidx/window/java/area/WindowAreaControllerJavaAdapter.kt
new file mode 100644
index 0000000..584445f
--- /dev/null
+++ b/window/window-java/src/main/java/androidx/window/java/area/WindowAreaControllerJavaAdapter.kt
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ * 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.window.java.area
+
+import android.app.Activity
+import androidx.core.util.Consumer
+import androidx.window.area.WindowAreaSessionCallback
+import androidx.window.area.WindowAreaStatus
+import androidx.window.area.WindowAreaController
+import androidx.window.core.ExperimentalWindowApi
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.asCoroutineDispatcher
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
+import java.util.concurrent.Executor
+import java.util.concurrent.locks.ReentrantLock
+import kotlin.concurrent.withLock
+
+/**
+ * An adapted interface for [WindowAreaController] that provides the information and
+ * functionality around RearDisplay Mode via a callback shaped API.
+ */
+@ExperimentalWindowApi
+class WindowAreaControllerJavaAdapter(
+    private val controller: WindowAreaController
+) : WindowAreaController by controller {
+
+    /**
+     * A [ReentrantLock] to protect against concurrent access to [consumerToJobMap].
+     */
+    private val lock = ReentrantLock()
+    private val consumerToJobMap = mutableMapOf<Consumer<*>, Job>()
+
+    /**
+     * Registers a listener to consume [WindowAreaStatus] values defined as
+     * [WindowAreaStatus.UNSUPPORTED], [WindowAreaStatus.UNAVAILABLE], and
+     * [WindowAreaStatus.AVAILABLE]. The values provided through this listener should be used
+     * to determine if you are able to enable rear display Mode at that time. You can use these
+     * values to modify your UI to show/hide controls and determine when to enable features
+     * that use rear display Mode. You should only try and enter rear display mode when your
+     * [consumer] is provided a value of [WindowAreaStatus.AVAILABLE].
+     *
+     * The [consumer] will be provided an initial value on registration, as well as any change
+     * to the status as they occur. This could happen due to hardware device state changes, or if
+     * another process has enabled RearDisplay Mode.
+     *
+     * @see WindowAreaController.rearDisplayStatus
+     */
+    fun addRearDisplayStatusListener(
+        executor: Executor,
+        consumer: Consumer<WindowAreaStatus>
+    ) {
+        val statusFlow = controller.rearDisplayStatus()
+        lock.withLock {
+            if (consumerToJobMap[consumer] == null) {
+                val scope = CoroutineScope(executor.asCoroutineDispatcher())
+                consumerToJobMap[consumer] = scope.launch {
+                    statusFlow.collect { consumer.accept(it) }
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes a listener of [WindowAreaStatus] values
+     * @see WindowAreaController.rearDisplayStatus
+     */
+    fun removeRearDisplayStatusListener(consumer: Consumer<WindowAreaStatus>) {
+        lock.withLock {
+            consumerToJobMap[consumer]?.cancel()
+            consumerToJobMap.remove(consumer)
+        }
+    }
+
+    /**
+     * Starts a RearDisplay Mode session and provides updates through the
+     * [WindowAreaSessionCallback] provided. Due to the nature of moving your Activity to a
+     * different display, your Activity will likely go through a configuration change. Because of
+     * this, if your Activity does not override configuration changes, this method should be called
+     * from a component that outlives the Activity lifecycle such as a
+     * [androidx.lifecycle.ViewModel]. If your Activity does override
+     * configuration changes, it is safe to call this method inside your Activity.
+     *
+     * This method should only be called if you have received a [WindowAreaStatus.AVAILABLE]
+     * value from the listener provided through the [addRearDisplayStatusListener] method. If
+     * you try and enable RearDisplay mode without it being available, you will receive an
+     * [UnsupportedOperationException].
+     *
+     * The [windowAreaSessionCallback] provided will receive a call to
+     * [WindowAreaSessionCallback.onSessionStarted] after your Activity has been moved to the
+     * display corresponding to this mode. RearDisplay mode will stay active until the session
+     * provided through [WindowAreaSessionCallback.onSessionStarted] is closed, or there is a device
+     * state change that makes RearDisplay mode incompatible such as if the device is closed so the
+     * outer-display is no longer in line with the rear camera. When this occurs,
+     * [WindowAreaSessionCallback.onSessionEnded] is called to notify you the session has been
+     * ended.
+     *
+     * @see addRearDisplayStatusListener
+     * @throws UnsupportedOperationException if you try and start a RearDisplay session when
+     * your [WindowAreaController.rearDisplayStatus] does not return a value of
+     * [WindowAreaStatus.AVAILABLE]
+     */
+    fun startRearDisplayModeSession(
+        activity: Activity,
+        executor: Executor,
+        windowAreaSessionCallback: WindowAreaSessionCallback
+    ) {
+        controller.rearDisplayMode(activity, executor, windowAreaSessionCallback)
+    }
+}
\ No newline at end of file
diff --git a/window/window-samples/build.gradle b/window/window-samples/build.gradle
index 3259f09..0312e03 100644
--- a/window/window-samples/build.gradle
+++ b/window/window-samples/build.gradle
@@ -46,7 +46,7 @@
     implementation "androidx.browser:browser:1.3.0"
     implementation("androidx.startup:startup-runtime:1.1.0")
 
-    implementation(project(":window:window"))
+    implementation(project(":window:window-java"))
     debugImplementation(libs.leakcanary)
 
     androidTestImplementation(libs.testCore)
diff --git a/window/window-samples/src/main/AndroidManifest.xml b/window/window-samples/src/main/AndroidManifest.xml
index de10c6a..76ad8e2 100644
--- a/window/window-samples/src/main/AndroidManifest.xml
+++ b/window/window-samples/src/main/AndroidManifest.xml
@@ -47,6 +47,16 @@
             android:exported="false"
             android:configChanges="orientation|screenSize|screenLayout|screenSize"
             android:label="@string/window_metrics"/>
+        <activity android:name=".RearDisplayActivityConfigChanges"
+            android:exported="true"
+            android:configChanges=
+                "orientation|screenLayout|screenSize|layoutDirection|smallestScreenSize"
+            android:label="@string/rear_display">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
         <activity
             android:name=".embedding.SplitActivityA"
             android:exported="true"
diff --git a/window/window-samples/src/main/java/androidx/window/sample/RearDisplayActivityConfigChanges.kt b/window/window-samples/src/main/java/androidx/window/sample/RearDisplayActivityConfigChanges.kt
new file mode 100644
index 0000000..f7e839f
--- /dev/null
+++ b/window/window-samples/src/main/java/androidx/window/sample/RearDisplayActivityConfigChanges.kt
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ * 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.window.sample
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat
+import androidx.core.util.Consumer
+import androidx.window.area.WindowAreaController
+import androidx.window.area.WindowAreaSessionCallback
+import androidx.window.area.WindowAreaSession
+import androidx.window.area.WindowAreaStatus
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.java.area.WindowAreaControllerJavaAdapter
+import androidx.window.sample.databinding.ActivityRearDisplayBinding
+import androidx.window.sample.infolog.InfoLogAdapter
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+import java.util.concurrent.Executor
+
+/**
+ * Demo Activity that showcases listening for RearDisplay Status
+ * as well as enabling/disabling RearDisplay mode. This Activity
+ * implements [WindowAreaSessionCallback] for simplicity.
+ *
+ * This Activity overrides configuration changes for simplicity.
+ */
+@OptIn(ExperimentalWindowApi::class)
+class RearDisplayActivityConfigChanges : AppCompatActivity(), WindowAreaSessionCallback {
+
+    private lateinit var windowAreaController: WindowAreaControllerJavaAdapter
+    private var rearDisplaySession: WindowAreaSession? = null
+    private val infoLogAdapter = InfoLogAdapter()
+    private lateinit var binding: ActivityRearDisplayBinding
+    private lateinit var executor: Executor
+
+    private val rearDisplayStatusListener = Consumer<WindowAreaStatus> { status ->
+        infoLogAdapter.append(getCurrentTimeString(), status.toString())
+        infoLogAdapter.notifyDataSetChanged()
+        updateRearDisplayButton(status)
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        binding = ActivityRearDisplayBinding.inflate(layoutInflater)
+        setContentView(binding.root)
+
+        executor = ContextCompat.getMainExecutor(this)
+        windowAreaController = WindowAreaControllerJavaAdapter(WindowAreaController.getOrCreate())
+
+        binding.rearStatusRecyclerView.adapter = infoLogAdapter
+
+        binding.rearDisplayButton.setOnClickListener {
+            if (rearDisplaySession != null) {
+                rearDisplaySession?.close()
+            } else {
+                windowAreaController.startRearDisplayModeSession(
+                    this,
+                    executor,
+                    this)
+            }
+        }
+    }
+
+    override fun onStart() {
+        super.onStart()
+        windowAreaController.addRearDisplayStatusListener(
+            executor,
+            rearDisplayStatusListener
+        )
+    }
+
+    override fun onStop() {
+        super.onStop()
+        windowAreaController.removeRearDisplayStatusListener(rearDisplayStatusListener)
+    }
+
+    override fun onSessionStarted(session: WindowAreaSession) {
+        rearDisplaySession = session
+        infoLogAdapter.append(getCurrentTimeString(), "RearDisplay Session has been started")
+        infoLogAdapter.notifyDataSetChanged()
+    }
+
+    override fun onSessionEnded() {
+        rearDisplaySession = null
+        infoLogAdapter.append(getCurrentTimeString(), "RearDisplay Session has ended")
+        infoLogAdapter.notifyDataSetChanged()
+    }
+
+    private fun updateRearDisplayButton(status: WindowAreaStatus) {
+        if (rearDisplaySession != null) {
+            binding.rearDisplayButton.isEnabled = true
+            binding.rearDisplayButton.text = "Disable RearDisplay Mode"
+            return
+        }
+        when (status) {
+            WindowAreaStatus.UNSUPPORTED -> {
+                binding.rearDisplayButton.isEnabled = false
+                binding.rearDisplayButton.text = "RearDisplay is not supported on this device"
+            }
+            WindowAreaStatus.UNAVAILABLE -> {
+                binding.rearDisplayButton.isEnabled = false
+                binding.rearDisplayButton.text = "RearDisplay is not currently available"
+            }
+            WindowAreaStatus.AVAILABLE -> {
+                binding.rearDisplayButton.isEnabled = true
+                binding.rearDisplayButton.text = "Enable RearDisplay Mode"
+            }
+        }
+    }
+
+    private fun getCurrentTimeString(): String {
+        val sdf = SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault())
+        val currentDate = sdf.format(Date())
+        return currentDate.toString()
+    }
+
+    private companion object {
+        private val TAG = RearDisplayActivityConfigChanges::class.java.simpleName
+    }
+}
\ No newline at end of file
diff --git a/window/window-samples/src/main/res/layout/activity_rear_display.xml b/window/window-samples/src/main/res/layout/activity_rear_display.xml
new file mode 100644
index 0000000..43bea60
--- /dev/null
+++ b/window/window-samples/src/main/res/layout/activity_rear_display.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  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.
+  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.
+  -->
+
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/rearStatusRecyclerView"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"/>
+
+    <Button
+        android:id="@+id/rear_display_button"
+        android:text="Enable RearDisplay"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAlignment="center"
+        android:layout_marginBottom="32dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/window/window-samples/src/main/res/values/strings.xml b/window/window-samples/src/main/res/values/strings.xml
index 5faaae6..25d5eef 100644
--- a/window/window-samples/src/main/res/values/strings.xml
+++ b/window/window-samples/src/main/res/values/strings.xml
@@ -51,4 +51,6 @@
     <string name="occlusion_is_none">Occlusion is none</string>
     <string name="window_metrics">Window metrics</string>
     <string name="window_metrics_description">Demo of using WindowMetrics API with activity handling rotations.</string>
+    <string name="rear_display">Rear Display Mode</string>
+    <string name="rear_display_description">Demo of observing to WindowAreaStatus and enabling/disabling RearDisplay mode</string>
 </resources>
diff --git a/window/window/api/public_plus_experimental_current.txt b/window/window/api/public_plus_experimental_current.txt
index e166e4b..3f1b25c 100644
--- a/window/window/api/public_plus_experimental_current.txt
+++ b/window/window/api/public_plus_experimental_current.txt
@@ -1,4 +1,36 @@
 // Signature format: 4.0
+package androidx.window.area {
+
+  @androidx.window.core.ExperimentalWindowApi public interface WindowAreaController {
+    method public default static androidx.window.area.WindowAreaController getOrCreate();
+    field public static final androidx.window.area.WindowAreaController.Companion Companion;
+  }
+
+  public static final class WindowAreaController.Companion {
+    method public androidx.window.area.WindowAreaController getOrCreate();
+  }
+
+  @androidx.window.core.ExperimentalWindowApi public interface WindowAreaSession {
+    method public void close();
+  }
+
+  @androidx.window.core.ExperimentalWindowApi public interface WindowAreaSessionCallback {
+    method public void onSessionEnded();
+    method public void onSessionStarted(androidx.window.area.WindowAreaSession session);
+  }
+
+  @androidx.window.core.ExperimentalWindowApi public final class WindowAreaStatus {
+    field public static final androidx.window.area.WindowAreaStatus AVAILABLE;
+    field public static final androidx.window.area.WindowAreaStatus.Companion Companion;
+    field public static final androidx.window.area.WindowAreaStatus UNAVAILABLE;
+    field public static final androidx.window.area.WindowAreaStatus UNSUPPORTED;
+  }
+
+  public static final class WindowAreaStatus.Companion {
+  }
+
+}
+
 package androidx.window.core {
 
   @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.WARNING) @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalWindowApi {
diff --git a/window/window/build.gradle b/window/window/build.gradle
index a66bf3a..f74ab83 100644
--- a/window/window/build.gradle
+++ b/window/window/build.gradle
@@ -64,6 +64,7 @@
     testImplementation(compileOnly(project(":window:extensions:extensions")))
 
     androidTestImplementation(libs.testCore)
+    androidTestImplementation(libs.kotlinTestJunit)
     androidTestImplementation(libs.testExtJunit)
     androidTestImplementation(libs.testRunner)
     androidTestImplementation(libs.testRules)
diff --git a/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt b/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt
new file mode 100644
index 0000000..dad5e14
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt
@@ -0,0 +1,213 @@
+/*
+ * 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.
+ * 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.window.area
+
+import android.annotation.TargetApi
+import android.app.Activity
+import android.content.pm.ActivityInfo
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.window.TestActivity
+import androidx.window.TestConsumer
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.extensions.area.WindowAreaComponent
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
+import org.junit.Assume.assumeTrue
+import org.junit.Rule
+import org.junit.Test
+import java.util.function.Consumer
+import kotlin.test.assertFailsWith
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Ignore
+
+@Ignore // todo(b/222407443)
+@OptIn(ExperimentalCoroutinesApi::class, ExperimentalWindowApi::class)
+class WindowAreaControllerImplTest {
+
+    @get:Rule
+    public val activityScenario: ActivityScenarioRule<TestActivity> =
+        ActivityScenarioRule(TestActivity::class.java)
+
+    private val testScope = TestScope(UnconfinedTestDispatcher())
+
+    @TargetApi(Build.VERSION_CODES.N)
+    @Test
+    public fun testRearDisplayStatus(): Unit = testScope.runTest {
+        assumeTrue(Build.VERSION.SDK_INT > Build.VERSION_CODES.N)
+        activityScenario.scenario.onActivity {
+            val extensionComponent = FakeWindowAreaComponent()
+            val repo = WindowAreaControllerImpl(extensionComponent)
+            val collector = TestConsumer<WindowAreaStatus>()
+            extensionComponent
+                .updateStatusListeners(WindowAreaComponent.STATUS_UNAVAILABLE)
+            testScope.launch {
+                repo.rearDisplayStatus().collect(collector::accept)
+            }
+            collector.assertValue(WindowAreaStatus.UNAVAILABLE)
+            extensionComponent
+                .updateStatusListeners(WindowAreaComponent.STATUS_AVAILABLE)
+            collector.assertValues(
+                WindowAreaStatus.UNAVAILABLE,
+                WindowAreaStatus.AVAILABLE
+            )
+        }
+    }
+
+    @Test
+    public fun testRearDisplayStatusNullComponent(): Unit = testScope.runTest {
+        activityScenario.scenario.onActivity {
+            val repo = EmptyWindowAreaControllerImpl()
+            val collector = TestConsumer<WindowAreaStatus>()
+            testScope.launch {
+                repo.rearDisplayStatus().collect(collector::accept)
+            }
+            collector.assertValue(WindowAreaStatus.UNSUPPORTED)
+        }
+    }
+
+    /**
+     * Tests the rear display mode flow works as expected. Tests the flow
+     * through WindowAreaControllerImpl with a fake extension. This fake extension
+     * changes the orientation of the activity to landscape when rear display mode is enabled
+     * and then returns it back to portrait when it's disabled.
+     */
+    @TargetApi(Build.VERSION_CODES.N)
+    @Test
+    public fun testRearDisplayMode(): Unit = testScope.runTest {
+        val extensions = FakeWindowAreaComponent()
+        val repo = WindowAreaControllerImpl(extensions)
+        extensions.currentStatus = WindowAreaComponent.STATUS_AVAILABLE
+        val callback = TestWindowAreaSessionCallback()
+        activityScenario.scenario.onActivity { testActivity ->
+            testActivity.resetLayoutCounter()
+            testActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+            testActivity.waitForLayout()
+        }
+
+        activityScenario.scenario.onActivity { testActivity ->
+            assert(testActivity.requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+            testActivity.resetLayoutCounter()
+            repo.rearDisplayMode(testActivity, Runnable::run, callback)
+        }
+
+        activityScenario.scenario.onActivity { testActivity ->
+            assert(testActivity.requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
+            assert(callback.currentSession != null)
+            testActivity.resetLayoutCounter()
+            callback.endSession()
+        }
+        activityScenario.scenario.onActivity { testActivity ->
+            assert(testActivity.requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+            assert(callback.currentSession == null)
+        }
+    }
+
+    @TargetApi(Build.VERSION_CODES.N)
+    @Test
+    public fun testRearDisplayModeReturnsError(): Unit = testScope.runTest {
+        val extensionComponent = FakeWindowAreaComponent()
+        extensionComponent.currentStatus = WindowAreaComponent.STATUS_UNAVAILABLE
+        val repo = WindowAreaControllerImpl(extensionComponent)
+        val callback = TestWindowAreaSessionCallback()
+        activityScenario.scenario.onActivity { testActivity ->
+            assertFailsWith(
+                exceptionClass = UnsupportedOperationException::class,
+                block = { repo.rearDisplayMode(testActivity, Runnable::run, callback) }
+            )
+        }
+    }
+
+    @Test
+    public fun testRearDisplayModeNullComponent(): Unit = testScope.runTest {
+        val repo = EmptyWindowAreaControllerImpl()
+        val callback = TestWindowAreaSessionCallback()
+        activityScenario.scenario.onActivity { testActivity ->
+            assertFailsWith(
+                exceptionClass = UnsupportedOperationException::class,
+                block = { repo.rearDisplayMode(testActivity, Runnable::run, callback) }
+            )
+        }
+    }
+
+    private class FakeWindowAreaComponent : WindowAreaComponent {
+        val statusListeners = mutableListOf<Consumer<Int>>()
+        var currentStatus = WindowAreaComponent.STATUS_UNSUPPORTED
+        var testActivity: Activity? = null
+        var sessionConsumer: Consumer<Int>? = null
+
+        @RequiresApi(Build.VERSION_CODES.N)
+        override fun addRearDisplayStatusListener(consumer: Consumer<Int>) {
+            statusListeners.add(consumer)
+            consumer.accept(currentStatus)
+        }
+
+        override fun removeRearDisplayStatusListener(consumer: Consumer<Int>) {
+            statusListeners.remove(consumer)
+        }
+
+        // Fake WindowAreaComponent will change the orientation of the activity to signal
+        // entering rear display mode, as well as ending the session
+        @RequiresApi(Build.VERSION_CODES.N)
+        override fun startRearDisplaySession(
+            activity: Activity,
+            rearDisplaySessionConsumer: Consumer<Int>
+        ) {
+            if (currentStatus != WindowAreaComponent.STATUS_AVAILABLE) {
+                throw WindowAreaController.REAR_DISPLAY_ERROR
+            }
+            testActivity = activity
+            sessionConsumer = rearDisplaySessionConsumer
+            testActivity!!.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+            rearDisplaySessionConsumer.accept(WindowAreaComponent.SESSION_STATE_ACTIVE)
+        }
+
+        @RequiresApi(Build.VERSION_CODES.N)
+        override fun endRearDisplaySession() {
+            testActivity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+            sessionConsumer?.accept(WindowAreaComponent.SESSION_STATE_INACTIVE)
+        }
+
+        @RequiresApi(Build.VERSION_CODES.N)
+        fun updateStatusListeners(newStatus: Int) {
+            currentStatus = newStatus
+            for (consumer in statusListeners) {
+                consumer.accept(currentStatus)
+            }
+        }
+    }
+
+    private class TestWindowAreaSessionCallback : WindowAreaSessionCallback {
+
+        var currentSession: WindowAreaSession? = null
+        var error: Throwable? = null
+
+        override fun onSessionStarted(session: WindowAreaSession) {
+            currentSession = session
+        }
+
+        override fun onSessionEnded() {
+            currentSession = null
+        }
+
+        fun endSession() = currentSession?.close()
+    }
+}
\ No newline at end of file
diff --git a/window/window/src/main/java/androidx/window/area/EmptyWindowAreaControllerImpl.kt b/window/window/src/main/java/androidx/window/area/EmptyWindowAreaControllerImpl.kt
new file mode 100644
index 0000000..996c7ad
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/EmptyWindowAreaControllerImpl.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ * 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.window.area
+
+import android.app.Activity
+import androidx.window.core.ExperimentalWindowApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOf
+import java.util.concurrent.Executor
+
+/**
+ * Empty Implementation for devices that do not
+ * support the [WindowAreaController] functionality
+ */
+@ExperimentalWindowApi
+internal class EmptyWindowAreaControllerImpl : WindowAreaController {
+    override fun rearDisplayStatus(): Flow<WindowAreaStatus> {
+        return flowOf(WindowAreaStatus.UNSUPPORTED)
+    }
+
+    override fun rearDisplayMode(
+        activity: Activity,
+        executor: Executor,
+        windowAreaSessionCallback: WindowAreaSessionCallback
+    ) {
+        throw WindowAreaController.REAR_DISPLAY_ERROR
+    }
+}
\ No newline at end of file
diff --git a/window/window/src/main/java/androidx/window/area/RearDisplaySessionImpl.kt b/window/window/src/main/java/androidx/window/area/RearDisplaySessionImpl.kt
new file mode 100644
index 0000000..9a5bbd3
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/RearDisplaySessionImpl.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ * 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.window.area
+
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.extensions.area.WindowAreaComponent
+
+@ExperimentalWindowApi
+internal class RearDisplaySessionImpl(
+    private val windowAreaComponent: WindowAreaComponent
+) : WindowAreaSession {
+
+    override fun close() {
+        windowAreaComponent.endRearDisplaySession()
+    }
+}
diff --git a/window/window/src/main/java/androidx/window/area/WindowAreaController.kt b/window/window/src/main/java/androidx/window/area/WindowAreaController.kt
new file mode 100644
index 0000000..05aa96e
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/WindowAreaController.kt
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ * 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.window.area
+
+import android.app.Activity
+import android.os.Build
+import android.util.Log
+import androidx.annotation.RestrictTo
+import androidx.window.core.BuildConfig
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.core.SpecificationComputer
+import androidx.window.extensions.WindowExtensionsProvider
+import androidx.window.extensions.area.WindowAreaComponent
+import kotlinx.coroutines.flow.Flow
+import java.util.concurrent.Executor
+import kotlin.jvm.Throws
+
+/**
+ * An interface to provide the information and behavior around moving windows between
+ * displays or display areas on a device.
+ */
+@ExperimentalWindowApi
+interface WindowAreaController {
+
+    /*
+    Marked with RestrictTo as we iterate and define the
+    Kotlin API we want to provide.
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public fun rearDisplayStatus(): Flow<WindowAreaStatus>
+
+    /*
+    Marked with RestrictTo as we iterate and define the
+    Kotlin API we want to provide.
+     */
+    @Throws(UnsupportedOperationException::class)
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public fun rearDisplayMode(
+        activity: Activity,
+        executor: Executor,
+        windowAreaSessionCallback: WindowAreaSessionCallback
+    )
+
+    public companion object {
+        internal val REAR_DISPLAY_ERROR =
+            UnsupportedOperationException("Rear Display mode cannot be enabled currently")
+
+        private val TAG = WindowAreaController::class.simpleName
+
+        private var decorator: WindowAreaControllerDecorator = EmptyDecorator
+
+        /**
+         * Provides an instance of [WindowAreaController].
+         */
+        @JvmName("getOrCreate")
+        @JvmStatic
+        public fun getOrCreate(): WindowAreaController {
+            var windowAreaComponentExtensions: WindowAreaComponent?
+            try {
+                windowAreaComponentExtensions = WindowExtensionsProvider
+                    .getWindowExtensions()
+                    .windowAreaComponent
+            } catch (t: Throwable) {
+                if (BuildConfig.verificationMode == SpecificationComputer.VerificationMode.STRICT) {
+                    Log.d(TAG, "Failed to load WindowExtensions")
+                }
+                windowAreaComponentExtensions = null
+            }
+            val controller =
+                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N ||
+                    windowAreaComponentExtensions == null) {
+                    EmptyWindowAreaControllerImpl()
+                } else {
+                    WindowAreaControllerImpl(windowAreaComponentExtensions)
+                }
+            return decorator.decorate(controller)
+        }
+
+        @JvmStatic
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        public fun overrideDecorator(overridingDecorator: WindowAreaControllerDecorator) {
+            decorator = overridingDecorator
+        }
+
+        @JvmStatic
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        public fun reset() {
+            decorator = EmptyDecorator
+        }
+    }
+}
+
+/**
+ * Decorator that allows us to provide different functionality
+ * in our window-testing artifact.
+ */
+@ExperimentalWindowApi
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public interface WindowAreaControllerDecorator {
+    /**
+     * Returns an instance of [WindowAreaController] associated to the [Activity]
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public fun decorate(controller: WindowAreaController): WindowAreaController
+}
+
+@ExperimentalWindowApi
+private object EmptyDecorator : WindowAreaControllerDecorator {
+    override fun decorate(controller: WindowAreaController): WindowAreaController {
+        return controller
+    }
+}
diff --git a/window/window/src/main/java/androidx/window/area/WindowAreaControllerImpl.kt b/window/window/src/main/java/androidx/window/area/WindowAreaControllerImpl.kt
new file mode 100644
index 0000000..0e156818
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/WindowAreaControllerImpl.kt
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ * 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.window.area
+
+import android.app.Activity
+import android.os.Build
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.window.core.BuildConfig
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.core.SpecificationComputer
+import androidx.window.extensions.area.WindowAreaComponent
+import kotlinx.coroutines.channels.BufferOverflow
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flow
+import java.util.concurrent.Executor
+import java.util.function.Consumer
+
+/**
+ * Implementation of WindowAreaController for devices
+ * that do implement the WindowAreaComponent on device.
+ *
+ * Requires [Build.VERSION_CODES.N] due to the use of [Consumer].
+ * Will not be created though on API levels lower than
+ * [Build.VERSION_CODES.S] as that's the min level of support for
+ * this functionality.
+ */
+@ExperimentalWindowApi
+@RequiresApi(Build.VERSION_CODES.N)
+internal class WindowAreaControllerImpl(
+    private val windowAreaComponent: WindowAreaComponent
+) : WindowAreaController {
+
+    private lateinit var rearDisplaySessionConsumer: Consumer<Int>
+    private var currentStatus: WindowAreaStatus? = null
+
+    override fun rearDisplayStatus(): Flow<WindowAreaStatus> {
+        return flow {
+            val channel = Channel<WindowAreaStatus>(
+                capacity = BUFFER_CAPACITY,
+                onBufferOverflow = BufferOverflow.DROP_OLDEST
+            )
+            val listener = Consumer<Int> { status ->
+                currentStatus = WindowAreaStatus.translate(status)
+                channel.trySend(currentStatus ?: WindowAreaStatus.UNSUPPORTED)
+            }
+            windowAreaComponent.addRearDisplayStatusListener(listener)
+            try {
+                for (item in channel) {
+                    emit(item)
+                }
+            } finally {
+                windowAreaComponent.removeRearDisplayStatusListener(listener)
+            }
+        }.distinctUntilChanged()
+    }
+
+    override fun rearDisplayMode(
+        activity: Activity,
+        executor: Executor,
+        windowAreaSessionCallback: WindowAreaSessionCallback
+    ) {
+        // If we already have a status value that is not [WindowAreaStatus.AVAILABLE]
+        // we should throw an exception quick to indicate they tried to enable
+        // RearDisplay mode when it was not available.
+        if (currentStatus != null && currentStatus != WindowAreaStatus.AVAILABLE) {
+            throw WindowAreaController.REAR_DISPLAY_ERROR
+        }
+        rearDisplaySessionConsumer =
+            RearDisplaySessionConsumer(windowAreaSessionCallback, windowAreaComponent)
+        windowAreaComponent.startRearDisplaySession(activity, rearDisplaySessionConsumer)
+    }
+
+    internal class RearDisplaySessionConsumer(
+        private val appCallback: WindowAreaSessionCallback,
+        private val extensionsComponent: WindowAreaComponent
+    ) : Consumer<Int> {
+
+        private var session: WindowAreaSession? = null
+
+        override fun accept(sessionStatus: Int) {
+            when (sessionStatus) {
+                WindowAreaComponent.SESSION_STATE_ACTIVE -> onSessionStarted()
+                WindowAreaComponent.SESSION_STATE_INACTIVE -> onSessionFinished()
+                else -> {
+                    if (BuildConfig.verificationMode ==
+                            SpecificationComputer.VerificationMode.STRICT) {
+                        Log.d(TAG, "Received an unknown session status value: $sessionStatus")
+                    }
+                    onSessionFinished()
+                }
+            }
+        }
+
+        private fun onSessionStarted() {
+            session = RearDisplaySessionImpl(extensionsComponent)
+            session?.let { appCallback.onSessionStarted(it) }
+        }
+
+        private fun onSessionFinished() {
+            session = null
+            appCallback.onSessionEnded()
+        }
+    }
+
+    internal companion object {
+        private val TAG = WindowAreaControllerImpl::class.simpleName
+        /*
+        Chosen as 10 for a base default value. We shouldn't be receiving
+        many changes to window area status so this is enough capacity
+        to not end up blocking.
+         */
+        private const val BUFFER_CAPACITY = 10
+    }
+}
diff --git a/window/window/src/main/java/androidx/window/area/WindowAreaSession.kt b/window/window/src/main/java/androidx/window/area/WindowAreaSession.kt
new file mode 100644
index 0000000..6cdbd12
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/WindowAreaSession.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ * 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.window.area
+
+import androidx.window.core.ExperimentalWindowApi
+
+/**
+ * Session interface to represent a long-standing
+ * WindowArea mode or feature that provides a handle
+ * to close the session.
+ */
+@ExperimentalWindowApi
+public interface WindowAreaSession {
+    fun close()
+}
\ No newline at end of file
diff --git a/window/window/src/main/java/androidx/window/area/WindowAreaSessionCallback.kt b/window/window/src/main/java/androidx/window/area/WindowAreaSessionCallback.kt
new file mode 100644
index 0000000..80842c4
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/WindowAreaSessionCallback.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ * 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.window.area
+
+import androidx.window.core.ExperimentalWindowApi
+
+/** Callback to update the client on the WindowArea Session being
+ * started and ended.
+ * TODO(b/207720511) Move to window-java module when Kotlin API Finalized
+ */
+@ExperimentalWindowApi
+interface WindowAreaSessionCallback {
+
+    fun onSessionStarted(session: WindowAreaSession)
+
+    fun onSessionEnded()
+}
\ No newline at end of file
diff --git a/window/window/src/main/java/androidx/window/area/WindowAreaStatus.kt b/window/window/src/main/java/androidx/window/area/WindowAreaStatus.kt
new file mode 100644
index 0000000..f60d8f5
--- /dev/null
+++ b/window/window/src/main/java/androidx/window/area/WindowAreaStatus.kt
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ * 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.window.area
+
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.extensions.area.WindowAreaComponent
+
+/**
+ * Represents a window area status.
+ */
+@ExperimentalWindowApi
+class WindowAreaStatus private constructor(private val mDescription: String) {
+    override fun toString(): String {
+        return mDescription
+    }
+
+    companion object {
+        /**
+         * Status representing that the WindowArea feature is not a supported
+         * feature on the device.
+         */
+        @JvmField
+        val UNSUPPORTED = WindowAreaStatus("UNSUPPORTED")
+
+        /**
+         * Status representing that the WindowArea feature is currently not available
+         * to be enabled. This could be due to another process has enabled it, or that the
+         * current device configuration doesn't allow it.
+         */
+        @JvmField
+        val UNAVAILABLE = WindowAreaStatus("UNAVAILABLE")
+
+        /**
+         * Status representing that the WindowArea feature is available to be enabled.
+         */
+        @JvmField
+        val AVAILABLE = WindowAreaStatus("AVAILABLE")
+
+        @JvmStatic
+        internal fun translate(status: Int): WindowAreaStatus {
+            return when (status) {
+                WindowAreaComponent.STATUS_AVAILABLE -> AVAILABLE
+                WindowAreaComponent.STATUS_UNAVAILABLE -> UNAVAILABLE
+                else -> UNSUPPORTED
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/window/window/src/test/java/androidx/window/area/WindowAreaStatusUnitTest.kt b/window/window/src/test/java/androidx/window/area/WindowAreaStatusUnitTest.kt
new file mode 100644
index 0000000..04d3702
--- /dev/null
+++ b/window/window/src/test/java/androidx/window/area/WindowAreaStatusUnitTest.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ * 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.window.area
+
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.extensions.area.WindowAreaComponent
+import org.junit.Test
+
+/**
+ * Unit tests for [WindowAreaStatus] that run on the JVM.
+ */
+@OptIn(ExperimentalWindowApi::class)
+class WindowAreaStatusUnitTest {
+
+    @Test
+    fun testWindowAreaStatusTranslateValueAvailable() {
+        val expected = WindowAreaStatus.AVAILABLE
+        val translateValue = WindowAreaStatus.translate(WindowAreaComponent.STATUS_AVAILABLE)
+        assert(expected == translateValue)
+    }
+
+    @Test
+    fun testWindowAreaStatusTranslateValueUnavailable() {
+        val expected = WindowAreaStatus.UNAVAILABLE
+        val translateValue = WindowAreaStatus.translate(WindowAreaComponent.STATUS_UNAVAILABLE)
+        assert(expected == translateValue)
+    }
+
+    @Test
+    fun testWindowAreaStatusTranslateValueUnsupported() {
+        val expected = WindowAreaStatus.UNSUPPORTED
+        val translateValue = WindowAreaStatus.translate(WindowAreaComponent.STATUS_UNSUPPORTED)
+        assert(expected == translateValue)
+    }
+}
\ No newline at end of file
diff --git a/work/work-runtime-ktx/api/2.7.0-beta01.txt b/work/work-runtime-ktx/api/2.7.0-beta01.txt
index 8535d65..2c5f419 100644
--- a/work/work-runtime-ktx/api/2.7.0-beta01.txt
+++ b/work/work-runtime-ktx/api/2.7.0-beta01.txt
@@ -5,8 +5,6 @@
     ctor public CoroutineWorker(android.content.Context appContext, androidx.work.WorkerParameters params);
     method public abstract suspend Object? doWork(kotlin.coroutines.Continuation<? super androidx.work.ListenableWorker.Result> p);
     method @Deprecated public kotlinx.coroutines.CoroutineDispatcher getCoroutineContext();
-    method public suspend Object? getForegroundInfo(kotlin.coroutines.Continuation<? super androidx.work.ForegroundInfo> p);
-    method public final com.google.common.util.concurrent.ListenableFuture<androidx.work.ForegroundInfo> getForegroundInfoAsync();
     method public final void onStopped();
     method public final suspend Object? setForeground(androidx.work.ForegroundInfo foregroundInfo, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public final suspend Object? setProgress(androidx.work.Data data, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
diff --git a/work/work-runtime-ktx/api/public_plus_experimental_2.7.0-beta01.txt b/work/work-runtime-ktx/api/public_plus_experimental_2.7.0-beta01.txt
index 8535d65..2d666e3 100644
--- a/work/work-runtime-ktx/api/public_plus_experimental_2.7.0-beta01.txt
+++ b/work/work-runtime-ktx/api/public_plus_experimental_2.7.0-beta01.txt
@@ -5,8 +5,8 @@
     ctor public CoroutineWorker(android.content.Context appContext, androidx.work.WorkerParameters params);
     method public abstract suspend Object? doWork(kotlin.coroutines.Continuation<? super androidx.work.ListenableWorker.Result> p);
     method @Deprecated public kotlinx.coroutines.CoroutineDispatcher getCoroutineContext();
-    method public suspend Object? getForegroundInfo(kotlin.coroutines.Continuation<? super androidx.work.ForegroundInfo> p);
-    method public final com.google.common.util.concurrent.ListenableFuture<androidx.work.ForegroundInfo> getForegroundInfoAsync();
+    method @androidx.work.ExperimentalExpeditedWork public suspend Object? getForegroundInfo(kotlin.coroutines.Continuation<? super androidx.work.ForegroundInfo> p);
+    method @androidx.work.ExperimentalExpeditedWork public final com.google.common.util.concurrent.ListenableFuture<androidx.work.ForegroundInfo> getForegroundInfoAsync();
     method public final void onStopped();
     method public final suspend Object? setForeground(androidx.work.ForegroundInfo foregroundInfo, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public final suspend Object? setProgress(androidx.work.Data data, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
diff --git a/work/work-runtime-ktx/api/restricted_2.7.0-beta01.txt b/work/work-runtime-ktx/api/restricted_2.7.0-beta01.txt
index 8535d65..2c5f419 100644
--- a/work/work-runtime-ktx/api/restricted_2.7.0-beta01.txt
+++ b/work/work-runtime-ktx/api/restricted_2.7.0-beta01.txt
@@ -5,8 +5,6 @@
     ctor public CoroutineWorker(android.content.Context appContext, androidx.work.WorkerParameters params);
     method public abstract suspend Object? doWork(kotlin.coroutines.Continuation<? super androidx.work.ListenableWorker.Result> p);
     method @Deprecated public kotlinx.coroutines.CoroutineDispatcher getCoroutineContext();
-    method public suspend Object? getForegroundInfo(kotlin.coroutines.Continuation<? super androidx.work.ForegroundInfo> p);
-    method public final com.google.common.util.concurrent.ListenableFuture<androidx.work.ForegroundInfo> getForegroundInfoAsync();
     method public final void onStopped();
     method public final suspend Object? setForeground(androidx.work.ForegroundInfo foregroundInfo, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
     method public final suspend Object? setProgress(androidx.work.Data data, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
diff --git a/work/work-runtime/api/2.7.0-beta01.txt b/work/work-runtime/api/2.7.0-beta01.txt
index a6de624..54713f5 100644
--- a/work/work-runtime/api/2.7.0-beta01.txt
+++ b/work/work-runtime/api/2.7.0-beta01.txt
@@ -154,7 +154,6 @@
   public abstract class ListenableWorker {
     ctor @Keep public ListenableWorker(android.content.Context, androidx.work.WorkerParameters);
     method public final android.content.Context getApplicationContext();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.work.ForegroundInfo!> getForegroundInfoAsync();
     method public final java.util.UUID getId();
     method public final androidx.work.Data getInputData();
     method @RequiresApi(28) public final android.net.Network? getNetwork();
@@ -216,11 +215,6 @@
   public static final class Operation.State.SUCCESS extends androidx.work.Operation.State {
   }
 
-  public enum OutOfQuotaPolicy {
-    enum_constant public static final androidx.work.OutOfQuotaPolicy DROP_WORK_REQUEST;
-    enum_constant public static final androidx.work.OutOfQuotaPolicy RUN_AS_NON_EXPEDITED_WORK_REQUEST;
-  }
-
   public final class OverwritingInputMerger extends androidx.work.InputMerger {
     ctor public OverwritingInputMerger();
     method public androidx.work.Data merge(java.util.List<androidx.work.Data!>);
@@ -347,7 +341,6 @@
     method public final B setBackoffCriteria(androidx.work.BackoffPolicy, long, java.util.concurrent.TimeUnit);
     method @RequiresApi(26) public final B setBackoffCriteria(androidx.work.BackoffPolicy, java.time.Duration);
     method public final B setConstraints(androidx.work.Constraints);
-    method public B setExpedited(androidx.work.OutOfQuotaPolicy);
     method public B setInitialDelay(long, java.util.concurrent.TimeUnit);
     method @RequiresApi(26) public B setInitialDelay(java.time.Duration);
     method public final B setInputData(androidx.work.Data);
diff --git a/work/work-runtime/api/public_plus_experimental_2.7.0-beta01.txt b/work/work-runtime/api/public_plus_experimental_2.7.0-beta01.txt
index a6de624..0c2f419 100644
--- a/work/work-runtime/api/public_plus_experimental_2.7.0-beta01.txt
+++ b/work/work-runtime/api/public_plus_experimental_2.7.0-beta01.txt
@@ -129,6 +129,9 @@
     enum_constant public static final androidx.work.ExistingWorkPolicy REPLACE;
   }
 
+  @experimental.Experimental(level=androidx.annotation.experimental.Experimental.Level.ERROR) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PACKAGE}) public @interface ExperimentalExpeditedWork {
+  }
+
   public final class ForegroundInfo {
     ctor public ForegroundInfo(int, android.app.Notification);
     ctor public ForegroundInfo(int, android.app.Notification, int);
@@ -154,7 +157,7 @@
   public abstract class ListenableWorker {
     ctor @Keep public ListenableWorker(android.content.Context, androidx.work.WorkerParameters);
     method public final android.content.Context getApplicationContext();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.work.ForegroundInfo!> getForegroundInfoAsync();
+    method @androidx.work.ExperimentalExpeditedWork public com.google.common.util.concurrent.ListenableFuture<androidx.work.ForegroundInfo!> getForegroundInfoAsync();
     method public final java.util.UUID getId();
     method public final androidx.work.Data getInputData();
     method @RequiresApi(28) public final android.net.Network? getNetwork();
@@ -216,7 +219,7 @@
   public static final class Operation.State.SUCCESS extends androidx.work.Operation.State {
   }
 
-  public enum OutOfQuotaPolicy {
+  @androidx.work.ExperimentalExpeditedWork public enum OutOfQuotaPolicy {
     enum_constant public static final androidx.work.OutOfQuotaPolicy DROP_WORK_REQUEST;
     enum_constant public static final androidx.work.OutOfQuotaPolicy RUN_AS_NON_EXPEDITED_WORK_REQUEST;
   }
@@ -347,7 +350,7 @@
     method public final B setBackoffCriteria(androidx.work.BackoffPolicy, long, java.util.concurrent.TimeUnit);
     method @RequiresApi(26) public final B setBackoffCriteria(androidx.work.BackoffPolicy, java.time.Duration);
     method public final B setConstraints(androidx.work.Constraints);
-    method public B setExpedited(androidx.work.OutOfQuotaPolicy);
+    method @androidx.work.ExperimentalExpeditedWork public B setExpedited(androidx.work.OutOfQuotaPolicy);
     method public B setInitialDelay(long, java.util.concurrent.TimeUnit);
     method @RequiresApi(26) public B setInitialDelay(java.time.Duration);
     method public final B setInputData(androidx.work.Data);
diff --git a/work/work-runtime/api/restricted_2.7.0-beta01.txt b/work/work-runtime/api/restricted_2.7.0-beta01.txt
index a6de624..54713f5 100644
--- a/work/work-runtime/api/restricted_2.7.0-beta01.txt
+++ b/work/work-runtime/api/restricted_2.7.0-beta01.txt
@@ -154,7 +154,6 @@
   public abstract class ListenableWorker {
     ctor @Keep public ListenableWorker(android.content.Context, androidx.work.WorkerParameters);
     method public final android.content.Context getApplicationContext();
-    method public com.google.common.util.concurrent.ListenableFuture<androidx.work.ForegroundInfo!> getForegroundInfoAsync();
     method public final java.util.UUID getId();
     method public final androidx.work.Data getInputData();
     method @RequiresApi(28) public final android.net.Network? getNetwork();
@@ -216,11 +215,6 @@
   public static final class Operation.State.SUCCESS extends androidx.work.Operation.State {
   }
 
-  public enum OutOfQuotaPolicy {
-    enum_constant public static final androidx.work.OutOfQuotaPolicy DROP_WORK_REQUEST;
-    enum_constant public static final androidx.work.OutOfQuotaPolicy RUN_AS_NON_EXPEDITED_WORK_REQUEST;
-  }
-
   public final class OverwritingInputMerger extends androidx.work.InputMerger {
     ctor public OverwritingInputMerger();
     method public androidx.work.Data merge(java.util.List<androidx.work.Data!>);
@@ -347,7 +341,6 @@
     method public final B setBackoffCriteria(androidx.work.BackoffPolicy, long, java.util.concurrent.TimeUnit);
     method @RequiresApi(26) public final B setBackoffCriteria(androidx.work.BackoffPolicy, java.time.Duration);
     method public final B setConstraints(androidx.work.Constraints);
-    method public B setExpedited(androidx.work.OutOfQuotaPolicy);
     method public B setInitialDelay(long, java.util.concurrent.TimeUnit);
     method @RequiresApi(26) public B setInitialDelay(java.time.Duration);
     method public final B setInputData(androidx.work.Data);
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/foreground/SystemForegroundDispatcher.java b/work/work-runtime/src/main/java/androidx/work/impl/foreground/SystemForegroundDispatcher.java
index ae4eb5c..b956663 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/foreground/SystemForegroundDispatcher.java
+++ b/work/work-runtime/src/main/java/androidx/work/impl/foreground/SystemForegroundDispatcher.java
@@ -253,6 +253,7 @@
         });
     }
 
+    @SuppressWarnings("deprecation")
     @MainThread
     private void handleNotify(@NonNull Intent intent) {
         int notificationId = intent.getIntExtra(KEY_NOTIFICATION_ID, 0);